问题 Oracle Java教程 - 静态类 - 教程中可能出现的错误


我是Java的新手,从Oracle Java教程学习Java。 我现在正在学习嵌套类,静态类和内部类。 我发现以下解释似乎很奇怪,我认为这是错误的。

从: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

嵌套类是其封闭类的成员。非静态嵌套类(内部类)可以访问封闭类的其他成员,即使它们被声明为私有。 静态嵌套类无权访问封闭类的其他成员

最后一句“静态嵌套类无法访问封闭类的其他成员”很奇怪,但可能引用实例成员,说静态类就像一个静态方法,无法访问实例变量。 但下一个注意事项甚至更奇怪:

注意: 静态嵌套类与其实例成员交互  外层阶级 (和其他课程) 就像任何其他顶级课程一样。实际上,静态嵌套类在行为上是一个顶级类,它已嵌套在另一个顶级类中以方便打包。

这看起来很奇怪,因为它意味着静态类无法访问外部类的私有实例成员。我编写了以下编译和运行的代码,并演示了静态类可以访问外部实例私有变量。

public class A {

    private int x;
    static private int y;


    static public class B{

        static void doSomething(){
            y++;
            System.out.println("y is now " + y );
        }

        static void doSomethingElse(A a)
        {
            a.x++;
            System.out.println("a.x is " + a.x );
        }
    }
}

// ------

public class Main {

    public static void main(String[] args){
        A a = new A();
        A.B b = new A.B();
        b.doSomething();
        b.doSomethingElse(a);
    }
}

这是教程中的错误,还是我可能不理解某些内容? 谢谢


1139
2017-09-02 11:03


起源

并提示:这些教程已被成千上万的人使用。它们是由绝对专家撰写的,可能会经过大量的评论。内容可能并不总是很清楚,但对于Java新手来说,在那里发现错误的可能性非常小。含义:这是一个安全的选择,教程是正确的:-) - GhostCat
是。这是一个合理的评论。我在这里发帖提问,以便更好地理解我不清楚的事情。但是,即使在本教程中,也会不时出现错误/疏忽。很奇怪,但也有一些。看到 stackoverflow.com/questions/52095760/...   和 stackoverflow.com/questions/51634863/... - Eliyahu M
不,他们(教程)并不完美,但我从我自己的经验中知道,99.999%的时间我认为我发现了一个错误(或者在Java本身),错误已经在我的自己的理解,而不是教程。也许你的数字更好,但这是我自己的经验。 - Hovercraft Full Of Eels


答案:


这是教程中的错误,还是我可能不理解某些内容?

你完全理解。教程页面充其量是误导性的。

这里有两个不同的概念:

  1. 您是否有权访问Java规则中的内容 访问控制 (例如,私人,包私人,受保护,公共)。

  2. “静态”的含义。 “内部”嵌套类的实例始终与封闭类的实例相关联(在内部类的隐藏实例字段中存储对封闭类实例的引用)。 “静态”嵌套类没有这个。

教程页面混淆了两个概念。

嵌套类是其封闭类的成员。

是的。

非静态嵌套类(内部类)可以访问封闭类的其他成员,即使它们被声明为私有。 静态嵌套类无权访问封闭类的其他成员。


3
2017-09-02 15:46





在教程中这是一个错误,或者我可能不理解somwthing?

错误在于您的理解和教程  正确。嵌套静态类中没有任何地方可以直接操作外部类的实例字段。我在谈论这些没有附加实例的字段 - 你无处可直接操作 x没有附加到 A 实例。

所以你可以这样做:

static void doSomethingElse(A a) {
    a.x++;  // x is part of the A instance passed into a parameter
    System.out.println("a.x is " + a.x );
}

但你不能这样做:

static void doSomethingElse2() {
    x++;
    System.out.println("x is " + x );
}

如果这个代码是相同的 B 是静态嵌套的或独立的非嵌套类。


你问:

“静态嵌套类与其外层类的实例成员交互,就像任何其他顶级类一样”?

正如上面所示 - 非静态嵌套类可以 直接互动 随着 a 场(如 doSomethingElse2() 显示)无需支持 A 实例,虽然静态嵌套类和独立类都不能。它们都需要单独的A实例,这里传递给你的实例 doSomethingElse(A a) 方法 参数


静态嵌套和独立之间的主要区别在于,前者(嵌套类)可以访问外部类的私有成员,而独立的则不能。也许这是你混乱的根源。


7
2017-09-02 11:08



句子的含义是什么?“静态嵌套类与其他外层类的实例成员交互,就像任何其他顶级类一样”? - Eliyahu M
@EliyahuM:请看编辑回答 - Hovercraft Full Of Eels
好。我明白。它意味着静态类必须具有对象实例才能引用其成员。这就像其他顶级课程一样。但是静态类仍然与其他顶级类不同,因为如果它具有外部类的实例,它可以访问实例私有成员。这有点令人困惑,我认为如果教程更清楚它会更好。无论如何,谢谢你的回答。 - Eliyahu M
@EliyahuM:是的,是的,他们确实可以访问私人网站。也许这就是你的困惑,访问修饰符状态和实例状态之间的差异 - Hovercraft Full Of Eels