你问:有什么诀窍可以让它编译吗?
答案是:嗯,也许....
创建如下所示的类:
public class A
{
public class B
{
public class X
{
}
}
}
以及将使用此类的类
public class AUse
{
public static void main(String[] args)
{
A.B.X aba = new A().new B().new X();
System.out.println("Created "+aba+" of class "+aba.getClass());
}
}
然后,下载 Apache 字节代码工程库 (BCEL),并创建并运行以下类:
import java.io.FileOutputStream;
import org.apache.bcel.Repository;
import org.apache.bcel.util.BCELifier;
public class CreateCreators
{
public static void main(String[] args) throws Exception
{
new BCELifier(
Repository.lookupClass("A"),
new FileOutputStream("ACreator.java")).start();
new BCELifier(
Repository.lookupClass("A$B"),
new FileOutputStream("A$BCreator.java")).start();
new BCELifier(
Repository.lookupClass("A$B$X"),
new FileOutputStream("A$B$XCreator.java")).start();
new BCELifier(
Repository.lookupClass("AUse"),
new FileOutputStream("AUseCreator.java")).start();
}
}
这使用 BCEL 中的类。这是一个类,它获取一个文件,并创建一个可以编译为文件的文件,该文件在执行时,将创建最初提供该文件的文件。(附注:我喜欢这个库)。BCELifier
.class
.java
.class
.class
因此,在此处创建的文件包含创建该文件所需的 BCEL 代码。这由常量池的生成和指令等语句组成:A$B$XCreator.java
A$B$X.class
...
_cg = new ClassGen("A$B$X", "java.lang.Object", "A.java",
ACC_PUBLIC | ACC_SUPER, new String[] { });
...
il.append(_factory.createFieldAccess("A$B$X", "this$1",
new ObjectType("A$B"), Constants.PUTFIELD));
同样,包含创建 .例如,构造函数调用 'A$B$X' 的指令:AUseCreator.java
AUse.class
...
il.append(_factory.createInvoke("A$B$X", "<init>", Type.VOID,
new Type[] { new ObjectType("A$B") }, Constants.INVOKESPECIAL));
现在,您只需将 和 中的 String 实例替换为 ,然后编译并运行这些类。"A$B$X"
"A$B$A"
A$B$XCreator.java
AUseCreator.java
结果将是一个文件,以及一个使用 .执行遗嘱打印A$B$A.class
AUse.class
A$B$A.class
AUse
Created A$B$A@15f5897 of class class A$B$A
我不确定这是否被认为是一种“技巧”,或者它是否仍然可以被称为“编译”,但至少有一种方法。当然,关键点是,它没有编译的事实仅仅是由于语言的限制,但是没有理由为什么它不应该以文件的形式表示,无论它们是如何创建的。class