Java编译器不能识别静态内部类 [英] Java compiler fails to recognise static inner class

查看:189
本文介绍了Java编译器不能识别静态内部类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个非常复杂的错误,所以请随身携带。



当我试图编译一些Java代码时,我看到一个奇怪的错误。编译器无法识别静态内部类。让我们说我正在处理一个类 MyClass 。我需要使用的静态内部类的FQN为 x.y.z.Parent.DesiredClass 。这个内部类是使用其FQN显式导入的。父级也使用其FQN导入。现在还有另一个包(另一个,不同的FQN),它有一个类 DesiredClass 。这个其他DesiredClass在类路径上,但它没有被显式导入。



在我继续之前,我应该明确表示,不可能改变这些类。



现在当我在代码中引用 Parent.DesiredClass 时,我使用 FQN Parent.DesiredClass 以避免任何可能的歧义。但是当我编译时,我得到一个错误,当我尝试实例化 Parent.DesiredClass 。我的代码段:

  x.y.z.Parent.DesiredClass dc; 
dc = new x.y.z.Parent.DesiredClass();

这会产生以下编译时错误:

  MyClass.java:123:包含xyzParent.DesiredClass的封闭实例是必需的
dc = new xyzParent.DesiredClass();
^

重要的是要注意,被链接的类是用不同的Java编译器:




  • MyClass 旨在使用Sun Java 1.4.2_18

  • xyzParent.DesiredClass 其他 DesiredClass 使用Microsoft Java 编译。



不幸的是,这些类不能用更现代的版本

此外,当实际尝试使用Sun Java 1.4.2_18进行编译时,编译器中会出现以下异常:

 编译器中发生异常(1.4.2_18)。请在检查Bug Parade的重复项之后,在Java开发人员连接(http://java.sun.com/cgi-bin/bugreport.cgi)提交错误。在您的报告中包括您的程序和以下诊断。谢谢。 
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)
运行Java编译器时遇到错误

中止编译。

如果我使用较新版本的Java(1.5版本)进行编译, ,但上述错误仍然出现。



任何人都可以解释这个错误吗?为什么编译器不能将静态内部类识别为静态,即使它是使用其FQN引用的?



您的帮助将非常感激。



==========



编辑:兔洞加深。经过进一步的调查,我发现问题是由一个单行代码在一个库中,我需要在我的路径中触发。我可以访问这个库的源代码,但不要编译它作为我的项目的一部分。代码行(让我们说它在类 TheirClass )正是我想要做的;即实例化 x.y.z.DesiredClass 。如果我删除 TheirClass (但不是在 MyClass )中的这行代码,那么我不会得到编译错误



因此,总之,以下工作:



strong> MyClass.java

  xyzParent.DesiredClass dc; 
dc = new x.y.z.Parent.DesiredClass();

TheirClass.java

  xyzParent.DesiredClass dc; 
dc = new x.y.z.Parent.DesiredClass();

以下确实工作:



MyClass.java

  xyzParent.DesiredClass dc; 
dc = new x.y.z.Parent.DesiredClass();

TheirClass.java

  // xyzParent.DesiredClass dc; 
// dc = new x.y.z.Parent.DesiredClass();

我将尝试并遵循@ Richard的建议并尽量减少代码,

解决方案

在忙于进行@Richard和@Stephen建议的低级调查时,我有几个想法关于这个问题。



我第一次尝试扩展 DesiredClass 与一个更含糊不清的名称,它会工作,如果我宁愿使用扩展类。 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编译器不能识别静态内部类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆