2015-06-25 16 views
9

Hat Java Shadow Type Parameter? Ich finde es schwierig, mich selbst zu testen, da Java-Generika zur Laufzeit nicht verdinglicht werden.Typdeklaration basierend auf Typparametern in inneren Klassen

Zum Beispiel gegeben dieser Code:

public class NestedGeneric<T> { 
    private InnerGeneric<T> innerGenericInstance; 

    private static class InnerGeneric<T> { 
     public T innerGenericField; 
    } 

    NestedGeneric() { 
    innerGenericInstance = new InnerGeneric<T>(); 
    } 
} 

Sowohl die folgenden Aussagen zusammenstellen fein:

NestedGeneric<Integer> test1 = new NestedGeneric<Integer>(); 
NestedGeneric.InnerGeneric<String> test2 = new NestedGeneric.InnerGeneric<String>(); 

Wenn die NestedGeneric einen Parametertyp übergeben wird und dessen Konstruktor aufgerufen, was ist T? Ist es immer der gleiche Typ wie der Typparameter, der an übergeben wird?

Mit anderen Worten, kann eine äußere Klassen Typ Parameter an eine innere Klassen generische Typ Deklarationen übergeben werden?

+1

Ja kann es, aber nicht zwingend. Sie könnten die innere Klasse auch zu einem anderen Objekt machen, aber Sie möchten das T in der geschachtelten Klassenerstellung in ein 'U' ändern. –

+0

Typparameter scheinen beschattet http://ideone.com/8DihKQ – ReyCharles

Antwort

6

Mit anderen Worten, ich nehme an, die Frage ist, kann eine äußere Klassen Typ Parameter an eine innere Klassen generische Typ Deklarationen übergeben werden?

No. Es gibt keine Beziehung (wie Vererbung oder als Feld) zwischen dem äußeren und der inneren statischen Klasse. Sie können ein Objekt der inneren statischen Klasse ohne Abhängigkeit von der äußeren Klasse wie in Ihrem Beispiel erstellen:

NestedGeneric.InnerGeneric<String> test2 = new NestedGeneric.InnerGeneric<String>(); 

Allerdings, wenn Sie eine Instanz der inneren Klasse als Feld des generische Typ abgeleitet wird, verwenden, um von die äußere Klasse:

private InnerGeneric<T> innerGenericInstance; 

innerGenericInstance = new InnerGeneric<T>(); 

eine dritte Variante wäre, die innere Klasse als ein Feld (nicht statisch) zu definieren:

private class InnerGeneric<T> { 
    public T innerGenericField; 
} 

, die jetzt den Typ von der äußeren Klasse abruft, da es sich um eine Elementvariable handelt.

Wie im Kommentar erwähnt definiert sowohl innere statische & äußere Klasse mit dem Typ wird nur verwirrt den Leser (und sich selbst zu einem späteren Zeitpunkt). Es sollte mit einem anderen generischen deklariert werden wie

public class NestedGeneric<T> { 
    private InnerGeneric<T> innerGenericInstance; 

    private static class InnerGeneric<U> { 
     private U innerGenericField; 
    } 

    NestedGeneric() { 
     innerGenericInstance = new InnerGeneric<T>(); 
    } 
} 
4

Ja, aber nicht mit dem statischen Modifikator:

public class NestedGeneric<T> { 
    private InnerGeneric<T> innerGenericInstance; 

    private class InnerGeneric<T> { 
     private T innerGenericField; 

     public InnerGeneric(T innerGenericField){ 
      this.innerGenericField = innerGenericField; 
     } 

     public T getInnerGenericField(){ 
      return this.innerGenericField; 
     } 
    } 

    NestedGeneric(T someGenericVariable) { 
     innerGenericInstance = new InnerGeneric<T>(someGenericVariable); 
     T innerGenericField = innerGenericInstance.innerGenericInstance(); 
    } 
} 
+0

In diesem Fall ist die innere generische Klasse nicht statisch, die anders behandelt wird – 6ton

+0

Die innere Klasse ist statisch, aber die Instanz der inneren Klasse ist in einem non gespeichert -static Elementvariable –

5

Dies ist kein Shadowing ist. In Ihrem Code gibt es nur einen Typparameter, den T Parameter. So sind innere und äußere T die gleichen Typparameter.

Sie können natürlich mehr Typparameter haben.

public class NestedGeneric<OUTER_TYPE> { 

    private static class InnerGeneric<INNER_TYPE> { 
    public INNER_TYPE innerGenericField; 
    } 

    public NestedGeneric() { 
    InnerGeneric<OUTER_TYPE> innerGenericInstance = new InnerGeneric<OUTER_TYPE>(); 

    InnerGeneric<String> secondInnerGenerics = new InnerGeneric<String>(); 
    } 
} 

Die INNER_TYPE und die OUTER_TYPE sind zwei verschiedene Typparameter. Zeile InnerGeneric<OUTER_TYPE> innerGenericInstance = new InnerGeneric<OUTER_TYPE>(); wird sagen, dass innerGenericInstance durch den gleichen Typ wie OUTER_TYPE parametriert ist. Aber sie müssen nicht gleich sein. So wie es bei secondInnerGenerics der Fall ist.

+0

Es ist also nur der Punkt der Erklärung wichtig? Selbst wenn sie anders benannt werden könnten, möchte ich das Verhalten verstehen, wenn sie gleich benannt sind. Wenn die Parameter der inneren Klassen den gleichen Namen wie die äußere Klasse tragen, sind sie noch völlig unabhängig? –

Verwandte Themen