7

今天,其他一些开发人员发现了一个带有一些有趣嵌套的 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 编译器试图通过不让我们创建与包含类同名的内部类来避免什么?

4

2 回答 2

6

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 编译器试图通过禁止嵌套声明与其外部类的名称冲突来保留这种能力。

于 2013-09-02T02:09:21.217 回答
0

创建一个complexType,然后引用第二层(同名)。使用不同的名称,这将创建一个不同的类并满足 java 要求。

IE

Choices = Choices.class
Choice = Choice.class
Choice(2nd level) = 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.InnerChoice 将分配给变量选择(变量名可以嵌套,而不是类名)

于 2013-11-11T18:59:18.890 回答