2010-12-15 17 views
11

ich so etwas wie dies in meinem api zur Verfügung stellen möchten:Nested generic in einer generischen Klasse

class Foobar extends AbstractThing<Double> 

class EventThing<Foobar> {  
      public Foobar getSource(); 
      public Double getValue(); 
} 

So schreibe ich dies:

class EventThing<T extends AbstractThing<U>> {  
     public T getSource(); 
     public U getValue(); 
} 

Aber java die U nicht auflösen kann.

Mit EventThing<T extends AbstractThing<U>,U> funktioniert es stattdessen, aber die zweite U ist eigentlich redundant, weil die AbtractThing den Typ bereits definieren. Also ich liebe es, es los zu werden.

Antwort

26

Sie können es nicht loswerden. Die zweite U ist nicht redundant. Sie möchten, dass der Compiler den ersten U als Typparameter interpretiert, tut dies aber nicht. Sie könnten auch diese geschrieben haben:

class EventThing<T extends AbstractThing<Double>> 

Beachten Sie, dass Double in diesem Fall eine konkrete Klasse ist, und nicht ein Typparameter. Vergleichen Sie dies mit den folgenden:

class EventThing<T extends AbstractThing<U>> 

Beachten Sie, dass dies die gleiche Form wie die erste Zeile des obigen Codes hat. Wie soll der Compiler wissen, dass im ersten Fall Double als konkrete Klasse gemeint ist, während im zweiten Fall U als Typparameter gemeint ist? Der Compiler kann das nicht wissen und behandelt U als eine konkrete Klasse, genau wie die Double in der ersten Zeile. Der einzige Weg, den Compiler zu informieren, dass U ist ein Typparameter als solche zu spezifizieren ist:

class EventThing<T extends AbstractThing<U>, U> 
+1

Es mir eher wie ein fehlendes Feature des Compilers scheint. EDIT: Aber ich verstehe Ihren Punkt, vielen Dank für Ihre Antwort. Zu schlecht. Ich denke, ich werde das Loch Feature verlassen. –

+4

@Marcel: Ich denke, diese Antwort erklärt ganz klar, warum der Compiler nicht versuchen kann, zu erraten, ob "U" ein tatsächlicher Typ oder ein generischer Typparameter ist. Java erfordert, dass jeder generische Typparameter aus gutem Grund explizit deklariert wird. Unabhängig davon, wie es Ihnen erscheint, ist dies kein "fehlendes Merkmal des Compilers". – ColinD

+1

@ColinD: Ich stimme Marcel zu, dass es wie ein fehlendes Feature scheint und U in seinem Beispiel scheint überflüssig. Offensichtlich muss der Compiler darüber informiert werden, dass U ein Typargument ist. Wir könnten etwas haben wie: class EventThing >, im Wesentlichen sagend: U ist ein variabler Typparameter, gehe jetzt und führe es selbst her (character% used nur zu Diskussionszwecken stimme ich zu, dass es hässlich ist). Auf diese Weise würde es keine Wiederholung im aufrufenden Code geben. – Gilead

Verwandte Themen