Oracle Java教程-静态类-教程中可能存在错误

Oracle Java教程-静态类-教程中可能存在错误,java,Java,我是Java新手,从Oracle Java教程学习Java。 我现在学习嵌套类、静态类和内部类。 我发现下面的解释似乎很奇怪,我认为这是错误的 发件人: 嵌套类是其封闭类的成员。非静态嵌套类(内部类)可以访问封闭类的其他成员,即使它们被声明为私有静态嵌套类无权访问封闭类的其他成员 最后一句“静态嵌套类无法访问封闭类的其他成员”很奇怪,但可能指的是实例成员,表示静态类类似于静态方法,无法访问实例变量。 但下一个音符更奇怪: 注意:静态嵌套类与其外部类(和其他类)的实例成员进行交互,就像任何其他顶级

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

发件人:

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

最后一句“静态嵌套类无法访问封闭类的其他成员”很奇怪,但可能指的是实例成员,表示静态类类似于静态方法,无法访问实例变量。 但下一个音符更奇怪:

注意:静态嵌套类与其外部类(和其他类)的实例成员进行交互,就像任何其他顶级类一样。实际上,静态嵌套类在行为上是一个顶级类,为了便于打包而嵌套在另一个顶级类中

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

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);
    }
}
这是教程中的一个错误,还是我可能理解得不好? 谢谢

这是教程中的一个错误,还是我没有很好地理解某些东西

错误在于您的理解,教程是正确的。在嵌套的静态类中,没有对外部类的实例字段进行任何直接操作。我所说的这些字段没有附加实例——如果不将
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)
方法参数中


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

这是教程中的一个错误,还是我可能理解得不好

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

这里有两个不同的概念:

  • 您是否有权访问Java访问控制规则范围内的内容(例如,私有、包私有、受保护、公共)

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

  • 教程页面混淆了这两个概念

    嵌套类是其封闭类的成员

    是的

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

    没有

    通过自己提供实例,您可以看到静态类确实可以访问封闭类的成员,包括私有实例字段,因此为什么
    a.x++编译。这就是访问

    通过使用“access”和“private”这两个词,该段强烈暗示它在Java语言规范中给出的定义范围内谈论访问控制。但事实并非如此。它只是试图解释概念#2,即封闭类的实例如何与嵌套类相关联。即使这样,它仍然是错误的,因为静态嵌套类肯定可以访问封闭类的静态成员,而段落中说它们没有。不管是谁写的那一页都很潦草

    注意:静态嵌套类与其外部类(和其他类)的实例成员进行交互。与任何其他顶级类一样。实际上,静态嵌套类在行为上是嵌套在另一顶级类中以便于打包的顶级类

    这一段仍在讨论静态的含义。虽然它有可能被误解,但它并没有试图说任何关于访问控制的话


    以下是正确的访问控制规则:

    [如果]成员或构造函数被声明为
    private
    ,[…]当且仅当它发生在包含成员或构造函数声明的顶级类(§7.6)的主体内时,才允许访问

    这个定义出人意料地简短,但它涵盖了这里所有相关的内容

    这意味着所有嵌套类(因为它们“在顶级类的主体内”)都可以访问封闭类的所有成员和构造函数,而不管嵌套类是静态的还是实例的,也不管被访问的类是否是