简体   繁体   English

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

[英]Static nested class has full access to private outer class members?

Update: 更新:

I'm still a unclear about this. 我还不清楚这一点。 I'm trying to find the JLS to describe this behaviour. 我正试图找到JLS来描述这种行为。 Instead, I found this quote in 8.3 of the JLS : 相反,我在JLS的8.3中找到了这个引用:

Member class declarations (§8.5) describe nested classes that are members of the surrounding class. 成员类声明(第8.5节)描述了作为周围类成员的嵌套类。 Member classes may be static, in which case they have no access to the instance variables of the surrounding class; 成员类可以是静态的,在这种情况下,它们无法访问周围类的实例变量; or they may be inner classes (§8.1.3). 或者他们可能是内部阶级(§8.1.3)。

Doesn't this mean the nested static class should not have access to the outer class variables? 这是不是意味着嵌套的静态类不应该访问外部类变量? Where can I find clarification of what the behaviour should be? 我在哪里可以找到应该是什么行为的澄清?

End Update 结束更新

I am seeking some clarification of the accesiblity of the private members of an outer class by an instance of a static nested class. 我正在寻求通过静态嵌套类的实例来澄清外部类的私有成员的可访问性。 The Java tutorials state: Java教程说明:

a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience 静态嵌套类在行为上是一个顶级类,它嵌套在另一个顶级类中以方便打包

The accepted answer from this question ( Java inner class and static nested class ) mentions: 这个问题的接受答案( Java内部类和静态嵌套类 )提到:

The only real conceivable reason to create a static inner class is that such a class has access to its containing class's private static members 创建静态内部类的唯一真正可能的原因是这样的类可以访问其包含类的私有静态成员

But it seems a static nested class also has access to the private members of any instance of the enclosing class ? 但似乎静态嵌套类也可以访问封闭类的任何实例的私有成员 This would be behaviourly different from any other top level class. 这将与任何其他顶级课程有所不同。 In the example below, the static nested class Builder can access the private members of any instance of the Config class. 在下面的示例中,静态嵌套类Builder可以访问Config类的任何实例的私有成员。 But another top level class would not be able to do this (eg an instance of ConfigTest would not be able to change the private members of a config object as shown in the commented manipulateConfig method. 但是另一个顶级类将无法执行此操作(例如, ConfigTest的实例将无法更改配置对象的私有成员,如注释的manipulateConfig方法中所示。

Am I understanding this correctly? 我理解正确吗? I haven't found a reference in the JLS to clarify this for me. 我没有在JLS中找到一个参考来为我澄清这一点。

Config: 配置:

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: 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");

    }

}

Output of running ConfigTest: 运行ConfigTest的输出:

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

The answer to which you link is not entirely correct: nested static classes have access to all members of its enclosing class, including private members. 您链接的答案并不完全正确:嵌套静态类可以访问其封闭类的所有成员,包括私有成员。

They do not get access to instance members, public or private, of its enclosing instance. 他们无法访问其封闭实例的实例成员(公共成员或私有成员)。 However, if you pass a method of a static nested class an instance of the enclosing class, the nested class would be able to access all members of the enclosing class, regardless of their access level. 但是,如果将静态嵌套类的方法传递给封闭类的实例,则嵌套类将能够访问封闭类的所有成员,而不管其访问级别如何。

I think the static/non-static confusion comes from this line of JLS : 我认为静态/非静态混淆来自这一系列的JLS

Member classes may be static, in which case they have no access to the instance variables of the surrounding class 成员类可以是静态的,在这种情况下,它们无法访问周围类的实例变量

This does not mean that static nested classes have no access to instance variables at all. 这并不意味着静态嵌套类根本无法访问实例变量。 It means that static nested classes have no access to instance variables of the enclosing class "for free", the way the non-static nested classes do. 这意味着静态嵌套类无法“免费”访问封闭类的实例变量,这是非静态嵌套类的实现方式。

To me, the two main differences between a static nested class and a top-level class are 对我来说,静态嵌套类和顶级类之间的两个主要区别是

  1. Nested static classes and interfaces express a closer association with their enclosing classes / interfaces. 嵌套的静态类和接口表达与它们的封闭类/接口更紧密的关联。 For example, Map.Entry nested interface is a better choice than MapEntry top-level interface for readability. 例如, Map.Entry嵌套接口是比MapEntry顶级接口更好的选择,以提高可读性。
  2. Nested classes can serve as an implementation detail of another class, if you declare them private. 如果您将其声明为私有,嵌套类可以充当另一个类的实现细节。 You cannot do that with top-level classes, because they would remain accessible at least to the classes in the same package. 你不能用顶级类做到这一点,因为它们至少可以访问同一个包中的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 静态嵌套类可以访问外部类的私有构造函数 - Static nested class has access to private constructor of outer class 如何从Java中的静态内部类访问外部类的私有成员 - How to access private members of outer class from static inner class in Java 为什么外部 Java 类可以访问内部类私有成员? - Why can outer Java classes access inner class private members? 公共嵌套类的子类无法访问封闭类的私有成员 - Subclass of a public nested class is unable to access private members of enclosing class 静态内部类如何访问外部类的所有静态数据成员和静态成员函数? - How does static inner class can access all the static data members and static member function of outer class? 为什么静态嵌套类不能访问外部类的“ this”指针? - Why can't a static nested class access “this” pointer of outer class? 验证对静态外部类的私有静态嵌套类的非静态方法的调用 - Verifying the calling of a non-static method of a private static nested class of a static outer class 静态嵌套类可以访问封闭类的哪些成员? - What members of the enclosing class can a static nested class access? 外部类可以访问内部类的成员吗? - Can an outer class access the members of inner class? Java:对外部类私有成员的匿名内部类实例初始化程序访问 - Java: Anonymous Inner Class Instance Initializer Access to Outer Class Private Members
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM