JAVA:静态vs内部类

Java: Static vs inner class

本问题已经有最佳答案,请猛点这里访问。

静态嵌套类和非静态嵌套类有什么区别?


根据定义,内部类不能是静态的,所以我将把您的问题重新定义为"静态和非静态嵌套类之间的区别是什么?"

非静态嵌套类对其嵌套的类的成员具有完全访问权限。静态嵌套类没有对嵌套实例的引用,因此静态嵌套类不能调用非静态方法或访问其嵌套的类的实例的非静态字段。


让我们来看看这些问题的智慧来源:Joshua Bloch的有效Java:

从技术上讲,没有静态的内部类。根据有效的Java,正确的术语是一个静态嵌套类。非静态嵌套类实际上是一个内部类,以及匿名类和本地类。

现在引用:

Each instance of a non-static nested class is implicitly associated
with an enclosing instance of its containing class... It is possible
to invoke methods on the enclosing instance.

静态嵌套类无权访问封闭实例。它也占用更少的空间。


静态内部类和非静态内部类有两种不同。

  • 在声明成员字段和方法的情况下,非静态内部类不能有静态字段和方法。但是,对于静态内部类,可以有静态和非静态字段方法。

  • 使用引用创建非静态内部类的实例它所定义的外部类的对象,这意味着它封闭实例。但是静态内部类的实例是创建时没有引用外部类,这意味着它没有封闭实例。

  • 请参阅此示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    class A
    {
        class B
        {
            // static int x; not allowed here
        }

        static class C
        {
            static int x; // allowed here
        }
    }

    class Test
    {
        public static void main(String… str)
        {
            A a = new A();

            // Non-Static Inner Class
            // Requires enclosing instance
            A.B obj1 = a.new B();

            // Static Inner Class
            // No need for reference of object to the outer class
            A.C obj2 = new A.C();
        }
    }


  • 静态内部类无法访问封闭类的非静态成员。它可以直接访问封闭类的静态成员(实例字段和方法),与获取值的过程样式相同,而无需创建对象。

  • 静态内部类可以声明静态成员和非静态成员。静态方法可以访问主类的静态成员。但是,它不能访问非静态的内部类成员。要访问非静态内部类的成员,必须创建非静态内部类的对象。

  • 非静态内部类不能声明静态字段和静态方法。它必须以静态或顶级类型声明。在这样做时,您会得到这个错误:"静态字段只能在静态或顶级类型中声明"。

  • 非静态内部类可以以获取值的过程样式访问封闭类的静态和非静态成员,但不能访问静态内部类的成员。

  • 封闭类在创建内部类的对象之前无法访问内部类的成员。如果主类在访问非静态类的成员时可以创建非静态内部类的对象。

  • 如果访问静态内部类的成员时的主类有两种情况:

    • 案例1:对于静态成员,可以使用静态内部类的类名
    • 案例2:对于非静态成员,它可以创建静态内部类的实例。

  • 正在讨论嵌套类…

    不同之处在于,也为静态的嵌套类声明可以在封闭类的外部实例化。

    当嵌套类声明不是静态的时,Java将不允许您实例化它,除非通过封闭类。从内部类创建的对象链接到从外部类创建的对象,因此内部类可以引用外部类的字段。

    但是如果它是静态的,那么链接就不存在了,外部字段就不能被访问(除了通过普通的引用,像任何其他对象一样),因此您可以自己实例化嵌套类。


    内部类不能是静态的,所以我将把您的问题重新定义为"静态和非静态嵌套类之间的区别是什么?".

    正如你在这里所说,内部类不能是静态的…我发现下面的代码是静态的……原因?或者哪个是正确的……

    是的,静态嵌套类型的语义中没有任何东西可以阻止您这样做。这段代码运行良好。

    1
    2
    3
    4
    5
    6
    7
    8
    9
        public class MultipleInner {
            static class Inner {
            }  
        public static void main(String[] args) {
            for (int i = 0; i < 100; i++) {
                new Inner();
            }
        }
    }

    这是发布在本网站上的代码…

    对于问题--->静态嵌套类是否可以多次实例化?

    答案是-->

    现在,当然嵌套类型可以执行自己的实例控制(例如私有构造函数、单例模式等),但这与它是嵌套类型这一事实无关。另外,如果嵌套类型是静态枚举,那么当然您根本无法实例化它。

    但一般来说,是的,静态嵌套类型可以多次实例化。

    注意,从技术上讲,静态嵌套类型不是"内部"类型。


    静态内部类:可以声明静态和非静态成员,但只能访问其父类的静态成员。

    非静态内部类:只能声明非静态成员,但可以访问其父类的静态和非静态成员。


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