Java编译器错误谜题:“内部类不能有静态声明” - 除了简单类型

9
在编码过程中,我遇到了一个奇怪的Java编译器行为。
当编译该类(以下是源代码)时,编译器会在NULL类变量上发出错误(“内部类不能有静态声明”)。这是符合预期的!
然而,对于ZERO类变量,没有生成错误。我不理解这个问题!
为什么会有这种差异,似乎允许在内部类中使用简单类型的静态声明,但不允许使用对象?
(javac -version: 1.6.0_24)
public class Outer {
    public static final Runnable HELLO = new Runnable() {
        // No compiler error
        public static final int ZERO = 0;

        // Causes compiler error: "inner classes cannot have static declarations"
        public static final Object NULL = null;

        @Override
        public void run() {
            System.out.println("Hello " + ZERO + NULL);
        }
    };
}

我认为这是因为原始变量将被视为常数并内联编译,而Object引用不会。我记得在这个YouTube视频中看到过编译器如何处理带有null引用的常量:http://www.youtube.com/watch?v=V1vQf4qyMXg&t=68m1s - Jimbali
无论是空引用还是“new Object()”引用都会导致编译器错误。 - Morten
1个回答

14

问题在于内部类无法拥有静态初始化块,而这种块是初始化非常量和非常量变量所必需的。


1
+1;有人可能会认为错误信息不够明确。第一个声明也是“静态的”。 - maba
也不知道为什么内部类不能有静态初始化块。 :| - Peter Lawrey
如果内部类不能有静态初始化块,为什么可以初始化静态简单类型类变量?Java语言规范的哪一部分允许其中一个但不允许另一个。我认为真正的问题是对于简单类型类变量(静态字段)没有生成编译器错误。 - Morten
1
简单的原始字段在字节码中具有默认值,它们不需要静态块来初始化。 - Peter Lawrey
4
好的,我接受任务。如maba所说,编译器错误“inner classes cannot have static declarations”严格来说是错误的(或者说最好是误导性的),因为内部类是允许拥有静态声明的。这个错误应该是类似于“内部类不能有静态初始化代码”,对吗? - Morten

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