Java 静态嵌套类对私有外部类成员具有完全访问权限?

Java 静态嵌套类对私有外部类成员具有完全访问权限?,java,inner-classes,Java,Inner Classes,更新: 我对此还不清楚。我试图找到JLS来描述这种行为。相反,我在以下文件中找到了这句话: 成员类声明(§8.5)描述了 周围班级的成员。成员类可以是静态的,例如 在这种情况下,他们无法访问 周边类;或者它们可以是内部类(§8.1.3) 这是否意味着嵌套的静态类不应该访问外部类变量?我在哪里可以找到关于行为应该是什么的澄清 结束更新 我想通过一个静态嵌套类的实例来澄清外部类的私有成员的可访问性。国家: 静态嵌套类在行为上是一个 嵌套在另一个顶级类中以方便打包 这个问题()的公认答案提到: 创建静

更新:

我对此还不清楚。我试图找到JLS来描述这种行为。相反,我在以下文件中找到了这句话:

成员类声明(§8.5)描述了 周围班级的成员。成员类可以是静态的,例如 在这种情况下,他们无法访问 周边类;或者它们可以是内部类(§8.1.3)

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

结束更新

我想通过一个静态嵌套类的实例来澄清外部类的私有成员的可访问性。国家:

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

这个问题()的公认答案提到:

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

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

我是否正确理解了这一点?我在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
        }

    }

}
运行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");

    }

}
Config{param1=Val1, param2=2}
Config{param1=Val1, param2=3}

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

它们无法访问其封闭实例的实例成员(公共或私有)。但是,如果将静态嵌套类的方法传递给封闭类的实例,则无论其访问级别如何,嵌套类都可以访问封闭类的所有成员

我认为静态/非静态混淆来自以下几行:

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

这并不意味着静态嵌套类根本无法访问实例变量,而是意味着静态嵌套类无法像非静态嵌套类那样“免费”访问封闭类的实例变量

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

  • 嵌套的静态类和接口与其封闭的类/接口表现出更紧密的关联。例如,
    Map.Entry
    Nested interface在可读性方面比
    MapEntry
    顶级接口更好
  • 嵌套类可以作为另一个类的实现细节,如果您将它们声明为私有的话。对于顶级类,您不能这样做,因为它们至少可以被同一个包中的类访问

  • 如果编译器允许您这样做…“静态内部”在术语上是矛盾的。您的意思是“静态嵌套”。@EJP感谢您的更正。我更改了可以找到的剩余术语错误用法。对于非静态嵌套类,访问封闭实例的私有成员对我来说是有意义的。但是对于静态嵌套类,没有enclosing实例,使嵌套类看起来可以访问外部类的任何其他实例的私有成员,如示例行
    anotherBuilder.modifyParm2(配置,3)中所示
    以上。我觉得这有点不对。@Glenn为什么?这对我来说很有意义:如果这两个类在功能上有很强的关联,但它们的实例之间没有一对一的关系,那么访问封闭类的私有成员的静态类提供了一个很好的选择。我想你是对的。这只是一个subtlTY我以前没有意识到,我找不到任何文档或评论来指出这个问题。然后我会考虑java教程注释<代码>静态嵌套类是行为上的顶层类,它被嵌套在另一个顶级类中,用于打包方便< /COD> >误导:紧耦合引入行为改变。e、 在我的示例中,我希望使用生成器生成不可修改的实例,这恰好是一个非常有用的属性。@Glenn我同意-我认为教程对材料的简化有点过分。为他们辩护,在静态类应该访问其封闭类的私有实例变量的情况下,使用用例在向读者介绍嵌套类概念的教程中很难解释这些问题。