这是一个相当复杂的错误,请耐心听我解释。
在编译一些Java代码时,我遇到了一个奇怪的错误。编译器无法识别一个静态内部类。假设我正在处理一个名为MyClass
的类。我需要使用的静态内部类具有x.y.z.Parent.DesiredClass
的完全限定名称。这个内部类是通过其完全限定名称显式导入的。父类也是通过其完全限定名称导入的。现在存在另一个包含DesiredClass
类的包(不同于前面提到的FQN),该类也在类路径下,但没有被显式导入。
在继续之前,我应该明确指出,无法更改这些类的名称。
现在,当我在我的代码中引用Parent.DesiredClass
时,我使用Parent.DesiredClass
的完全限定名称来避免任何可能的歧义。但是当我编译时,当我尝试实例化Parent.DesiredClass
时,我会得到一个错误。我的代码片段:
x.y.z.Parent.DesiredClass dc;
dc = new x.y.z.Parent.DesiredClass();
这会产生以下编译时错误:
MyClass.java:123: an enclosing instance that contains x.y.z.Parent.DesiredClass is required
dc = new x.y.z.Parent.DesiredClass();
^
请注意,被链接的类是使用不同的Java编译器编译的:
MyClass
旨在使用Sun Java 1.4.2_18进行编译x.y.z.Parent.DesiredClass
和另一个DesiredClass
是使用Microsoft Java编译的。
此外,在尝试使用Sun Java 1.4.2_18进行编译时,以下异常会在编译器中发生:
An exception has occurred in the compiler (1.4.2_18). Please file a bug at the Java Developer Connection (http://java.sun.com/cgi-bin/bugreport.cgi) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.NullPointerException
at com.sun.tools.javac.v8.code.Type.isSubTypes(Type.java:557)
at com.sun.tools.javac.v8.comp.Resolve.instantiate(Resolve.java:221)
at com.sun.tools.javac.v8.comp.Resolve.selectBest(Resolve.java:317)
at com.sun.tools.javac.v8.comp.Resolve.findMethod(Resolve.java:414)
...
at com.sun.tools.javac.v8.comp.Attr.attribClass(Attr.java:1332)
at com.sun.tools.javac.v8.JavaCompiler.compile(JavaCompiler.java:355)
at com.sun.tools.javac.v8.Main.compile(Main.java:569)
at com.sun.tools.javac.Main.compile(Main.java:36)
at com.sun.tools.javac.Main.main(Main.java:27)
Error encountered running Java Compiler
Aborting compilation.
如果我使用更新版本的Java(1.5或更高版本)编译,编译器异常不会发生,但仍会发生上述错误。请问有人能解释一下这个错误吗?为什么编译器没有将静态内部类识别为静态,即使使用了它的FQN也是如此?非常感谢您的帮助。
编辑: 经过进一步调查,我发现问题是由我需要在路径中拥有一个库中的单行代码触发的。我可以访问此库的源代码,但不将其编译为我的项目的一部分。这行代码(假设在类TheirClass中)正是我想要做的事情:即实例化x.y.z.DesiredClass。如果我删除TheirClass中的此行代码(但不删除MyClass中的此行代码),则不会收到编译错误。
因此,总结如下:以下内容不起作用:
MyClass.java:
x.y.z.Parent.DesiredClass dc;
dc = new x.y.z.Parent.DesiredClass();
TheirClass.java:
x.y.z.Parent.DesiredClass dc;
dc = new x.y.z.Parent.DesiredClass();
以下内容是可行的:
MyClass.java:
x.y.z.Parent.DesiredClass dc;
dc = new x.y.z.Parent.DesiredClass();
TheirClass.java:
//x.y.z.Parent.DesiredClass dc;
//dc = new x.y.z.Parent.DesiredClass();
我将尝试遵循@Richard的建议,尽可能地减少代码量,以便我可以发布一个样例。
DesiredClass
的代码吗?你遇到的错误通常是在没有封闭类的实例的情况下尝试实例化非静态内部类时看到的。 - selig