2010-12-15 19 views
11

quiero dar algo como esto en mi api:anidada genérica en una clase genérica

class Foobar extends AbstractThing<Double> 

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

así que escribir esto:

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

Pero Java no puede resolver el U.

Con EventThing<T extends AbstractThing<U>,U> en su lugar funciona, pero el segundo U es realmente redundante porque el AbtractThing ya define el Tipo. Entonces me encanta deshacerme de eso.

Respuesta

26

No puede deshacerse de él. El segundo U no es redundante. Desea que el compilador interprete el primer U como parámetro de tipo, pero no es así. También podría haber escrito esto:

class EventThing<T extends AbstractThing<Double>> 

Tenga en cuenta que Double en este caso es una clase concreta, y no un parámetro de tipo. Compare esto con lo siguiente:

class EventThing<T extends AbstractThing<U>> 

Tenga en cuenta que tiene exactamente la misma forma que la primera línea del código anterior. ¿Cómo se supone que el compilador debe saber que en el primer caso, Double se entiende como una clase concreta, mientras que en el segundo caso, U se entiende como un parámetro de tipo?

El compilador no puede saber eso, y trata el U como una clase concreta, como el Double en la primera línea. La única manera para que el compilador sabe que U es un parámetro de tipo es especificar como tal:

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

Me parece más a una característica que falta del compilador. EDITAR: Pero entiendo su punto, gracias por su respuesta. Para mal. Creo que dejaré la característica del hoyo. –

+4

@Marcel: Creo que esta respuesta explica con bastante claridad por qué el compilador no puede (y no debe) intentar adivinar si 'U' es un tipo real o un parámetro de tipo genérico. Java requiere que cada parámetro de tipo genérico sea declarado explícitamente por una buena razón. Independientemente de lo que te parezca, esta no es una "característica que falta en el compilador". – ColinD

+1

@ColinD: estoy de acuerdo con Marcel en que parece una característica faltante y U en su ejemplo parece redundante. Mientras, obviamente, el compilador debe ser informado de que U es un argumento tipo, podríamos tener algo como: class EventThing >, diciendo esencialmente: U es un parámetro de tipo variable, ahora ve e infórmalo tú mismo (character% used solo para discusión, estoy de acuerdo que es feo). De esta manera no habría repetición en el código de llamada. – Gilead

Cuestiones relacionadas