问题描述
这是一个非常复杂的错误,所以请随身携带。
当我试图编译一些Java代码时,我看到一个奇怪的错误。编译器无法识别静态内部类。让我们说我正在处理一个类 c>使用尝试实例化 DesiredClass Class.forName():
DesiredClass dc;
try {
dc =(DesiredClass)Class.forName(classname).newInstance();
}
catch(Exception e){
}
效果很好!
即使这有点乱,也让我继续我的工作。我想知道什么是错误的根本原因(可能是编译器使用的类加载器的一些问题,特别是考虑到有类已经编译了不同的品牌编译器?),但成本 -
感谢所有贡献的人。
This is quite a complicated error, so please bear with me.
I am seeing a weird error when trying to compile some Java code. The compiler fails to recognise a static inner class. Let us say that I am working on a class MyClass. The static inner class which I need to use has an FQN of x.y.z.Parent.DesiredClass. This inner class is explicitly imported using its FQN. The parent is also imported using its FQN. Now there exists another package with (another, different FQN) which has a class DesiredClass. This other DesiredClass is on the classpath, but it is not being explicitly imported.
Before I continue I should make it clear that it is not possible to change the names of these classes.
Now when I reference Parent.DesiredClass in my code, I use the FQN of Parent.DesiredClass to avoid any possible ambiguity. But when I compile I get an error when I try to instantiate Parent.DesiredClass. My code snippet:
x.y.z.Parent.DesiredClass dc; dc = new x.y.z.Parent.DesiredClass();
This produces the following compile time error:
MyClass.java:123: an enclosing instance that contains x.y.z.Parent.DesiredClass is required dc = new x.y.z.Parent.DesiredClass(); ^
It is important to note that the classes being linked to were compiled with different Java compilers:
- MyClass is intended to be compiled with Sun Java 1.4.2_18
- x.y.z.Parent.DesiredClass and the other DesiredClass were compiled using Microsoft Java.
Again, unfortunately, these classes cannot be recompiled with more modern versions of Java.
Additionally, when actually trying to compile with Sun Java 1.4.2_18, the following exception occurs within the compiler:
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.
If I compile with a newer version of Java (1.5 onwards), then the compiler exception does not occur, but the abovementioned error still occurs.
Can anyone please explain this error? Why does the compiler not recognise the static inner class as static, even if it is referred to using its FQN?
Your help will be greatly appreciated.
==========
EDIT: The rabbit hole deepens. After further investigation I found that the problem is triggered by a single line of code in one of the libraries which I need to have in my path. I have access to the source code of this library, but do not compile it as part of my project. The line of code (let's say it's in class TheirClass) does exactly what I am trying to do; i.e., instantiating x.y.z.DesiredClass. If I remove this line of code in TheirClass (but not in MyClass), then I do not get the compile error.
So, in summary, the following does not work:
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();
The following does work:
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();
I am going to try and follow @Richard's advice and minimise the code so that I can post a sample of it.
While still busy doing the low level investigations suggested by @Richard and @Stephen, I had a couple of ideas about this issue.
I first tried to extend DesiredClass with one which has a less ambiguous name and then see if it would work if I rather use the extended class. It did not and caused the same error.
I then tried to instantiate DesiredClass using Class.forName():
DesiredClass dc; try { dc = (DesiredClass) Class.forName(classname).newInstance(); } catch (Exception e) { }
This worked!
Even though this is a bit messy, it allows me to continue with my work. I would love to know what the root cause of the error is (perhaps some problem with the class loader which the compiler uses, especially considering that there are classes which have been compiled with different "brands" of compilers?), but the cost-benefit of spending more time trying to figure this out is not worth it.
Thank you to everyone who contributed.
这篇关于Java编译器不能识别静态内部类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!