Java 与外部类同名的内部类? 限制条件:

Java 与外部类同名的内部类? 限制条件:,java,inner-classes,Java,Inner Classes,我有一个我编写的maven源代码生成器,它正在创建POJO类 从某些具有嵌套名称空间的数据文件。我希望每个名称空间 可以作为内部类嵌套。在某些情况下,我失去了控制 具有与最外层的简单名称相同的内部类 班级 所有类都必须是publicscope,因为这是类型安全的 包装在类似于属性文件的东西上,但具有层次结构 我不能更改名称,否则我将更改名称的含义和名称空间 这是封闭的数据 鉴于此,我有以下代码: 内部类应该附加外部类的名称以形成一个唯一的名称空间,例如a$B$a.class,我还没有找到一个不编

我有一个我编写的maven源代码生成器,它正在创建POJO类 从某些具有嵌套名称空间的数据文件。我希望每个名称空间 可以作为内部类嵌套。在某些情况下,我失去了控制 具有与最外层的简单名称相同的内部类 班级

所有类都必须是
public
scope,因为这是类型安全的 包装在类似于属性文件的东西上,但具有层次结构

我不能更改名称,否则我将更改名称的含义和名称空间 这是封闭的数据

鉴于此,我有以下代码: 内部类应该附加外部类的名称以形成一个唯一的名称空间,例如
a$B$a.class
,我还没有找到一个不编译的有效原因


有什么诀窍可以让它编译吗?你不能让它编译,但更重要的是,你为什么要这么做

有什么问题吗

public class A
{
    public class B
    {
        public class InnerA
        {

        }
    }
}
这似乎是一个需要解决的设计问题。如果不能重命名它,请考虑匿名内部类。或者到外面去上课。或者干脆不使用它们。

如果一个类与它的任何封闭类或接口具有相同的简单名称,则这是一个编译时错误


注意:在我第一次寻找明确的规则时,我不知怎的错过了这一点。如果你想要我在这里的曲折方式,请检查编辑历史记录。

这有点像黑客,但这是在我的机器上编译的:

class A
{
    public class B
    {
        public class Α
        {

        }
    }
}
字面意思:复制过去这件事;)

扰流板:

内部类的名称是希腊字母表中的大写字母alpha。它是一个Unicode字符


根据您所追求的目标,以下内容可能适用于您:

public class A {
  class B extends C {
  }

  public static void main(String[] args) {
    new A().new B().new A();
  }
}

class C {
  class A {
    {
      System.out.println(getClass());
    }
  }
}

你问:有什么技巧可以让它编译吗?

答案是:嗯,也许

创建如下所示的类:

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());
    }
}
然后,下载,创建并运行以下类:

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
文件。(旁注:我喜欢这个图书馆)

因此,在那里创建的
A$B$XCreator.java
文件包含创建
A$B$X.class
文件所需的BCEL代码。这包括诸如生成常量池之类的语句和说明:

...
_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));
类似地,
AUseCreator.java
包含创建
AUse.class
的BCEL代码。例如,构造函数调用'A$B$X'的指令:

...
il.append(_factory.createInvoke("A$B$X", "<init>", Type.VOID, 
    new Type[] { new ObjectType("A$B") }, Constants.INVOKESPECIAL));


我不确定这是否被视为一个“把戏”,或者它是否仍然可以被称为“编译”,但至少有一种方法。当然,这里的关键点是,它没有编译完全是由于语言的限制,但是没有理由不以
文件的形式表示,不管它们是如何创建的

看在上帝的份上:为什么?好吧,没有。对于所有说“那么就不要那样做”的回答者来说:这是一个有趣的理论问题,“它不起作用”并不是特别有反应。这个把戏有什么限制?一个明显的伎俩是“重命名”,但我怀疑你是否愿意。对于一个被认为有效的技巧,结果的哪些属性应该是真的?如果外部a需要是公共的呢?我的意思是,这个问题有一个公共的外部a…是的,我知道,但我在另一个Java文件中测试了这个,你只能有一个公共类。这不是黑客:)如果你想公开它:)这不会在我的机器上编译。Unicode似乎不受支持。。。还有,这是一个正常的a。我赞扬你的创造力,但诅咒任何在真实代码中使用这个的人。不幸的是,这只是一种奇特的重命名方式。
...
il.append(_factory.createInvoke("A$B$X", "<init>", Type.VOID, 
    new Type[] { new ObjectType("A$B") }, Constants.INVOKESPECIAL));
Created A$B$A@15f5897 of class class A$B$A