2

In the code below, I am wondering why the run() in the inline class is able to access the outer class variable - semaphore (even though it is not declared final).

    private Semaphore semaphore = new Semaphore(bufferSize);

    private Runnable producerRunnable = new Runnable(){

        @Override
        public void run()
        {
            try
            {
                semaphore.acquire();
            }
            catch(InterruptedException e)
            {
                System.out.println("producer was interrupted while trying to acquire semaphore");                   
            }
        }
   };

I expected Eclipse to flag a compilation error - since semaphore reference is not declared final

Hari
  • 5,057
  • 9
  • 41
  • 51

2 Answers2

2

This is normal. The final requirement is only described to apply to local variables and parameters (JLS):

Any local variable, formal parameter, or exception parameter used but not declared in an inner class must either be declared final [...].

Members of the enclosing instance don't need to be final to access them.

Radiodef
  • 37,180
  • 14
  • 90
  • 125
0

Because you have defined semaphore as a global variable to that class and all the local variables should be declared as final if you want to access it in the runnable .

public class KamalTest {

    /**
     * @param args the command line arguments
     */
    private Semaphore semaphore = new Semaphore(2);
    private Runnable producerRunnable = new Runnable() {
        @Override
        public void run() {
            try {
                semaphore.acquire();
            } catch (InterruptedException e) {
                System.out.println("producer was interrupted while trying to acquire semaphore");
            }
        }
    };

    public void startThread1() {
        Thread th = new Thread(producerRunnable);
        th.start();
    }

    public void startThread2() {
        final Semaphore semPhore = new Semaphore(2);

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    semPhore.acquire();
                } catch (InterruptedException ex) {
                    Logger.getLogger(KamalTest.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };


        Thread th = new Thread(runnable);
        th.start();
    }

    public static void main(String[] args) {

        KamalTest kt = new KamalTest();
        kt.startThread1();


        System.out.println("Internet Available : " + isInternetAvailable());

    }
}


}
maverick
  • 171
  • 1
  • 9