今天,其他一些开发人员发现了一个带有一些有趣嵌套的XML模式,JAXB将其编译成这样的结构:
public class Choices
{
public static class Choice
{
public static class Choice
{
}
}
}
如果你试图编译这个,Java编译器说,
class Choices.Choice is already defined in class Choices
当然还有最里面的class Choice
声明上的下划线。
但我要说的是,类Choices.Choice
并不是它试图声明的。相反,它试图声明Choices.Choice.Choice
,这将是一个不同的类。
有趣的是,这很好:
public class OuterClass
{
public static class Inner1
{
public static class Inner2
{
}
}
public static class Inner2
{
public static class Inner1
{
}
}
}
但这是被禁止的:
public class OuterClass
{
public static class Inner1
{
public static class Inner2
{
public static class Inner1
{
}
}
}
}
所以我想规则是类的名称在任何级别上都不能与包含类的名称相同。显然,这里的修复方法是已知的——让JAXB不要生成无效代码。
但我的问题是,为什么会出现这种限制?Java编译器不允许我们创建与包含类同名的内部类,这是为了避免什么?
Java允许您在不完全指定其名称的情况下引用外部类,如下所示:
public static class Inner1
{
public static class Inner2
{
public static class Inner3
{
public void demo() {
Class<Inner2> c = Inner2.class; // This is allowed
}
}
}
}
如果类的嵌套允许在层次结构的任何级别使用相同的名称,则不可能使用非限定名称进行引用。Java编译器正试图通过禁止嵌套声明与其外部类的名称冲突来保留这种能力。
创建一个complexType,然后引用第二级(同名)。使用不同的名称,这将创建不同的类并满足java需求。
即
Choices=选择.class
Choice=选择.class
选择(二级)=InnerChoice.class
<complexType name = "innerChoice" >
<sequence>
.....
</sequence>
</complexType>
<element name="choices">
<complexType>
<sequence>
<element name="choice">
<complexType>
<sequence>
<!-- NEW! -->
<element name="choice" type="innerChoice">
<!- This used to say
<element name="choice">
<complextype>
<sequence>
....
</sequence>
</complexType>
-->
.....
现在,您生成的类文件将是Choices.Choice.InerChoice,它将被分配给变量Choice(变量名可以嵌套,而不是类名)