4

我在 Eclipse 和我的 JDK 认为合法的 java 之间遇到了一个有趣的差异。

Eclipse 可以顺利编译以下类,而 Mac OS X 上的 JDK 会产生以下错误。

public class Builder {  
    private class Item {}

    public void addItem(Item i) {}

    public static void main(String[] args) {
        new Builder() {{
            addItem(new Item());
        }};
    }
}

 

$ javac Builder.java 
Builder.java:9: non-static variable this cannot be referenced from a static context
            addItem(new Item());
                    ^
1 error

使Item类静态解决了这个问题,但它让我有点好奇:Eclipse 是否宽容并编译实际上无效的代码?我是否偶然发现了 Mac OS X JDK 的古怪之处?我错过了什么吗?

更新 可能与包括以下内容有关

$ java -version
java version "1.6.0_33"
Java(TM) SE Runtime Environment (build 1.6.0_33-b03-424-11M3720)
Java HotSpot(TM) 64-Bit Server VM (build 20.8-b03-424, mixed mode)

更新 2

使 Item 更可见(默认、受保护或公共)也满足 JDK 编译器的要求。

4

5 回答 5

4

javac 1.7.0_04 编译源代码没有错误,所以我建议这是 javac 1.6 中的一个错误。

于 2012-08-06T19:24:42.300 回答
2

我得到了相同的结果,但有趣的是,将代码更改为:

new Builder() {{
    addItem(this.new Item());
}};

(应该相同)产生不同的错误消息:

Builder.java:9: Builder.Item has private access in Builder
            addItem(this.new Item());

我怀疑这是真正的潜在错误 -Item该类是私有的,因此在匿名子类中不可见。更改Item为受保护而不是私有允许原始版本和this.new版本都成功编译。

于 2012-08-06T19:25:31.227 回答
1

在 Eclipse 中,默认情况下Access to a non-accessible member of an enclosing type可能会被忽略。如果你去 Project->Properties->Java Compiler->Errors/Warning 你可以启用项目特定的设置。

差异可能是因为 Eclipse 带有它自己的编译器 - JDT的一部分,它的作用与javac.

于 2012-08-06T19:20:08.740 回答
0

我认为这是eclipse编译器中的一个错误。内部 Item 类不是静态的,因此您只能通过 Builder 对象访问它,如下所示:

new Builder().new Item()

在静态块中初始化 Item 类,您没有 Builder 的实例,因此您发布的这段代码不应该工作。非常有趣的错误。

于 2012-08-06T19:13:34.323 回答
-2

将静态添加到项目的类声明中,例如static class Item {}

于 2012-08-06T19:09:28.840 回答