为什么无法在内部类中使用初始化块来初始化静态变量?

6
为什么Java不允许在非静态内部类中使用静态初始化块进行静态声明?下面的代码中,outer2可以正常工作,而inner2则不行,尽管它们做的是相同的事情。有什么想法吗?我不是在寻找解决方法,只是想理解为什么Java不能这样做。
public class WhyUNoStatic {
    public static final String outer1 = "snth";  // ok
    public static final String outer2;  // ok
    static
    {
        outer2 = "snth";
    }

    public class Inner {
        public static final String inner1 = "snth";  // still ok! 
        public static final String inner2;  // FAILURE TIME
        static
        {
            inner2 = "snth";
        }
    }
}

编辑:请注意,inner1 是可以正常工作的。并不是Java禁止在内部类中使用静态变量,只是禁止它们的声明。


2
因为内部类不能拥有 static 的非终态成员,但是 static { } 是一个静态成员。这可能是原因? - Luiggi Mendoza
Java禁止内部类中的非常量变量。 inner1是一个常量变量。 inner2不是。 - Sotirios Delimanolis
2个回答

2

JLS第8.1.3节禁止这种行为。

如果内部类声明了一个静态初始化器(§8.7),则会在编译时出错。

如果内部类声明了一个明确或隐含的静态成员,除非该成员是常量变量(§4.12.4),否则会在编译时出错。

您在内部类中将static变量声明为final是可以的,但静态初始化器在此处被禁止。


至于为什么,这可能会使已经相当复杂的初始化序列变得更加复杂。 - biziclop
是的,这就是我想表达的。为什么编译器不能处理这个?我很想看到一个代码示例来说明编译器处理这个问题的困难之处... - acushner

2

请参阅JLS第8章

如果内部类(inner classes)声明了静态初始化器(§8.7)或成员接口,则会发生编译时错误。

而你可以声明一个嵌套类(nested class)来代替它。

public static class Inner {...}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接