Why can outer Java classes access inner class priv

2018-12-31 14:47发布

I observed that Outer classes can access inner classes private instance variables. How is this possible? Here is a sample code demonstrating the same:

class ABC{
    class XYZ{
        private int x=10;
    }

    public static void main(String... args){
        ABC.XYZ xx = new ABC().new XYZ();
        System.out.println("Hello :: "+xx.x); ///Why is this allowed??
    }
}

Why is this behavior allowed?

10条回答
牵手、夕阳
2楼-- · 2018-12-31 15:11

There's a correct answer appearing on another question similar to this: Why can the private member of an nested class be accessed by the methods of the enclosing class?

It says there's a definition of private scoping on JLS - Determining Accessibility:

Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.

查看更多
浅入江南
3楼-- · 2018-12-31 15:12

The inner class is (for purposes of access control) considered to be part of the containing class. This means full access to all privates.

The way this is implemented is using synthetic package-protected methods: The inner class will be compiled to a separate class in the same package (ABC$XYZ). The JVM does not support this level of isolation directly, so that at the bytecode-level ABC$XYZ will have package-protected methods that the outer class uses to get to the private methods/fields.

查看更多
旧时光的记忆
4楼-- · 2018-12-31 15:15

An IMHO important use case for inner classes is the factory pattern. The enclosing class may prepare an instance of the inner class w/o access restrictions and pass the instance to the outside world, where private access will be honored.

In contradiction to abyx declaring the class static doesn't change access restrictions to the enclosing class, as shown below. Also the access restrictions between static classes in the same enclosing class are working. I was surprised ...

class MyPrivates {
    static class Inner1 { private int test1 = 2; }
    static class Inner2 { private int test2 = new Inner1().test1; }

    public static void main(String[] args) {
        System.out.println("Inner : "+new Inner2().test2);
    }
}
查看更多
宁负流年不负卿
5楼-- · 2018-12-31 15:15

Inner class is regarded as an attribute of the Outer class. Therefore, no matter the Inner class instance variable is private or not, Outer class can access without any problem just like accessing its other private attributes(variables).

class Outer{

private int a;

class Inner{
private int b=0;
}

void outMethod(){
a = new Inner().b;
}
}
查看更多
初与友歌
6楼-- · 2018-12-31 15:17

Because your main() method is in the ABC class, which can access its own inner class.

查看更多
与风俱净
7楼-- · 2018-12-31 15:19

If you like to hide the private members of your inner class, you may define an Interface with the public members and create an anonymous inner class that implements this interface. Example bellow:

class ABC{
    private interface MyInterface{
         void printInt();
    }

    private static MyInterface mMember = new MyInterface(){
        private int x=10;

        public void printInt(){
            System.out.println(String.valueOf(x));
        }
    };

    public static void main(String... args){
        System.out.println("Hello :: "+mMember.x); ///not allowed
        mMember.printInt(); // allowed
    }
}
查看更多
登录 后发表回答