2013-09-02 5 views
5

Heute fand einige andere Entwickler ein XML-Schema mit einigen interessanten Verschachtelung, die in eine Struktur wie folgt zusammengestellt JAXB:Warum kann ich keine innere Klasse mit zwei Ebenen und demselben Namen wie die Klasse, die sie enthält, haben?

public class Choices 
{ 
    public static class Choice 
    { 
     public static class Choice 
     { 
     } 
    } 
} 

Wenn Sie dies zu kompilieren versuchen, sagt der Java-Compiler,

class Choices.Choice is already defined in class Choices 

mit natürlich die Unterstreichung auf der innersten class Choice Erklärung.

Aber ich sage, Klasse Choices.Choice ist nicht, was es versuchte zu deklarieren. Stattdessen wurde versucht, Choices.Choice.Choice zu deklarieren, was eine andere Klasse wäre.

Interessanterweise ist es in Ordnung:

public class OuterClass 
{ 
    public static class Inner1 
    { 
     public static class Inner2 
     { 
     } 
    } 

    public static class Inner2 
    { 
     public static class Inner1 
     { 
     } 
    } 
} 

Aber das ist verboten:

public class OuterClass 
{ 
    public static class Inner1 
    { 
     public static class Inner2 
     { 
      public static class Inner1 
      { 
      } 
     } 
    } 
} 

Also ich denke, die Regel ist, dass der Name einer Klasse nicht das gleiche wie ein enthalten sein können Klasse auf jedem Niveau. Offensichtlich ist die Behebung hier bereits bekannt - lassen Sie JAXB keinen ungültigen Code generieren.

Aber meine Frage ist, warum ist diese Einschränkung sogar vorhanden? Was versucht der Java-Compiler zu vermeiden, indem wir nicht eine innere Klasse mit demselben Namen wie eine umschließende Klasse erstellen lassen?

+0

Eine bessere Frage könnte sein, warum würden Sie wan t es zu tun. – Bohemian

+0

Nun, um ehrlich zu sein, ich nicht. Wie gesagt, es war JAXBs Code-Generation, die es generiert hat. – Trejkaz

+0

Nun, ich würde sagen, dass das eigentliche Problem ein schlecht entworfenes XML-Schema ist. –

Antwort

5

Java können Sie auf eine äußere Klasse verweisen, ohne Angabe ihres vollständigen Namens, wie folgt aus:

public static class Inner1 
{ 
    public static class Inner2 
    { 
     public static class Inner3 
     { 
      public void demo() { 
       Class<Inner2> c = Inner2.class; // This is allowed 
      } 
     } 
    } 
} 

Verschachtelung von Klassen hatten die Verwendung von identischen Namen auf jeder Ebene der Hierarchie erlaubt, durch unqualifizierte Namen referenzieren würde war unmöglich. Diese Fähigkeit versucht der Java-Compiler zu bewahren, indem er verschachtelten Deklarationen verbietet, mit Namen ihrer äußeren Klassen zu kollidieren.

0

Erstellen Sie einen complexType, und beziehen Sie sich dann auf die zweite Ebene (desselben Namens). Verwenden Sie einen anderen Namen, dies erstellt eine andere Klasse und erfüllt die Java-Anforderungen.

dh

Choices = Choices.class
Wahl = Choice.class
Wahl (Teil 2) = 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> 
      --> 
      ..... 

jetzt Ihre generierten Klassendateien werden Choices.Choice .InnerChoice, das der Variablenauswahl zugewiesen wird (Variablennamen können verschachtelt werden, keine Klassennamen)

+0

Wie gesagt, das Schema gehört uns nicht. Es ist ein Standard. – Trejkaz

Verwandte Themen