有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

非静态内部类中的java静态变量

首先我想问Why does Java prohibit static fields in inner classes?,但问题已经存在了。我给出的需要它们的理由(serialVersionUID)被博兹霍的回答消除了。不过,我还是很好奇:

静态字段是否仅在源代码或类文件中被禁止

顺便说一句,一个令人信服的理由,为什么这是禁止尚未发明。在C语言中,即使在函数内部也允许使用静态变量。它们的寿命与任何其他静态变量相同,只是它们的可见性不同。同样的方法也适用于Java


共 (3) 个答案

  1. # 1 楼答案

    如果它们被设计成允许静态的东西,就不会发生什么糟糕的事情。在类文件级别没有问题,我认为字节码没有内部类的概念

    不过,这会令人困惑:

    class X
        class Y
            static int z;
    
    X x1 = new X();
    X.Y y1 = x1.new Y();    
    
    X x2 = new X();
    X.Y y2 = x2.new Y();    
    X.Y y3 = x2.new Y();    
    

    直观地说,y2y3应该共享相同的z,但它应该是y1看到的相同的z


    从概念上讲,内部类仅在外部实例中有效。甚至可以想象,当外部实例被GC’ed时,JVM会卸载它;[1]中给出的反对类卸载的参数不适用,因为内部类没有静态变量或静态初始值设定项

    然而现实是,所有内部实例都共享一个类,而不管外部实例如何。这当然是正确的:y1.getClass()==y2.getClass()==y3.getClass()

    可以说,语言规范规定它是真实的:[2]

    Two reference types are the same run-time type if ... defined by the same class loader, and have the same binary name

    y1的类和y2的类具有相同的类装入器,X.Y的二进制名称定义良好,独立于外部实例。因此y1和y2必须具有相同的运行时类

    如果语言规范实际上暗示内部类独立于外部实例,那么对内部类中静态的普遍接受的解释就被削弱了


    [1]http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7

    [2]http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.3.4

  2. # 2 楼答案

    内部类可以定义静态字段:

    Inner classes may not declare static members, unless they are compile-time constant fields (§15.28).

    因此,您可以定义一个串行版本id

    当静态字段不是常量时,那么它是逻辑上不允许的-静态字段不需要类的实例-它们是每个类的,而内部类需要拥有类的实例-没有实例它们就不能存在。虽然静态字段可以是内部类,但它们的定义就好像它们在所属类中一样,这会让人更加困惑

  3. # 3 楼答案

    静态成员不允许仅在非静态内部类的情况下使用,bcz非静态内部类还充当外部类的方法,因此方法的所有规则都适用于内部类。。我们可以在静态内部类中声明静态成员

    基本规则

    1. 非静态内部类不允许静态方法静态内部类
    2. 静态内部类允许从静态到非静态的一切