Accessing a private element through an inline created object in java

rematnarab :

I am new to java and trying some accessing methods and i encountered something that i do not understand. The code below working fine, prints 9 and not giving any compilation errors. I think this code should give a compilation error and number should be inaccessible from the test method, since new Human() is an instance of a totally different class. Can anybody explain me what is happening here ?

public class Test{      
    public static void main(String[] args) {
        int number = 9;

        test("holla",new Human(){   
            @Override
            void test() {
                // TODO Auto-generated method stub
                System.out.println(number); // I think this line should not compile
            }               
        });    
    }

    private static void test(String a ,Human h){            
        h.test();           
    }    
} 

Human Class

public abstract class Human {       
    abstract void test();    
}
GhostCat salutes Monica C. :

This is perfectly valid (for java8 - prior to that, you would need thje final keyword when declaring number):

  • you create an anonymous inner class that extends Human and provides the required implementation of the test() method.
  • that method is using a variable from its enclosing "scope" - and the compiler is smart enough to detect that this variable is in fact a constant - as there no other subsequent assignments to it.

In order to "invalidate" your example: simply add an assignment

number = 42; 

within the main method - after defining that anonymous inner class. Or use some version of java that is older than java8.

Keep in mind that anonymous inner classes are closures, and that the JVM is copying the values that are required "inside" from the outside. But when the outside value changes - which value should be copied. See here for further reading.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=458726&siteId=1