静态嵌套类是否可以完全访问私有外部类成员?

Gle*_*enn 6 java inner-classes

更新:

我还不清楚这一点.我正试图找到JLS来描述这种行为.相反,我在JLS的8.3中找到了这个引用:

成员类声明(第8.5节)描述了作为周围类成员的嵌套类.成员类可以是静态的,在这种情况下,它们无法访问周围类的实例变量; 或者他们可能是内部阶级(§8.1.3).

这是不是意味着嵌套的静态类不应该访问外部类变量?我在哪里可以找到应该是什么行为的澄清?

结束更新

我正在寻求通过静态嵌套类的实例来澄清外部类的私有成员的可访问性.在Java教程状态:

静态嵌套类在行为上是一个顶级类,它嵌套在另一个顶级类中以方便打包

这个问题的接受答案(Java内部类和静态嵌套类)提到:

创建静态内部类的唯一真正可能的原因是这样的类可以访问其包含类的私有静态成员

但似乎静态嵌套类也可以访问封闭类的任何实例的私有成员?这将与任何其他顶级课程有所不同.在下面的示例中,静态嵌套类Builder可以访问该类的任何实例的私有成员Config.但是另一个顶级类将无法做到这一点(例如,一个实例ConfigTest将无法更改配置对象的私有成员,如注释manipulateConfig方法中所示.

我理解正确吗?我没有在JLS中找到一个参考来为我澄清这一点.

配置:

public class Config {

    private String param1;
    private int param2;

    private Config() {}

    public String getParam1() { return param1; }
    public int getParam2() { return param2; }

    @Override
    public String toString() {
        return "Config{" + "param1=" + param1 + ", param2=" + param2 + '}';
    }



    public static class Builder {

        private String param1;
        private int param2;

        public Builder setParam1(String param1) { this.param1 = param1; return this; }
        public Builder setParam2(int param2) { this.param2 = param2; return this; }

        public Config build() {
            Config config = new Config();
            config.param1 = param1;  // <- Accessing private member of outer class
            config.param2 = param2;
            return config;
        }


        public void modifyParm2(Config config, int newVal) {
            config.param2 = newVal;  // <- Able to modify private member of any enclosing class
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

ConfigTest:

public class ConfigTest {


    private Config getConfig() {

        Config.Builder builder = new Config.Builder();

        Config config = builder
                .setParam1("Val1")
                .setParam2(2)
                .build();

        return config;

    }

//    private void manipulateConfig(Config config, String newParam1) {
//        config.param1 = newParam1;
//    }

    public static void main(String[] args) {

        ConfigTest configTest = new ConfigTest();
        Config config = configTest.getConfig();
        System.out.println(config);

        Config.Builder anotherBuilder = new Config.Builder();
        anotherBuilder.modifyParm2(config, 3);
        System.out.println(config);

//        configTest.manipulateConfig(config, "val11");

    }

}
Run Code Online (Sandbox Code Playgroud)

运行ConfigTest的输出:

Config{param1=Val1, param2=2}
Config{param1=Val1, param2=3}
Run Code Online (Sandbox Code Playgroud)

das*_*ght 9

您链接的答案并不完全正确:嵌套静态类可以访问其封闭类的所有成员,包括私有成员.

他们无法访问其封闭实例的实例成员(公共成员或私有成员).但是,如果将静态嵌套类的方法传递给封闭类的实例,则嵌套类将能够访问封闭类的所有成员,而不管其访问级别如何.

我认为静态/非静态混淆来自这一系列的JLS:

成员类可以是静态的,在这种情况下,它们无法访问周围类的实例变量

这并不意味着静态嵌套类根本无法访问实例变量.这意味着静态嵌套类无法"免费"访问封闭类的实例变量,这是非静态嵌套类的实现方式.

对我来说,静态嵌套类和顶级类之间的两个主要区别是

  1. 嵌套的静态类和接口表达与它们的封闭类/接口更紧密的关联.例如,Map.Entry嵌套接口是比MapEntry顶级接口更好的选择,以提高可读性.
  2. 如果您将其声明为私有,嵌套类可以充当另一个类的实现细节.你不能用顶级类做到这一点,因为它们至少可以访问同一个包中的类.