2010-12-15 79 views
11

Je veux donner quelque chose comme ça dans mon api:générique dans Nested une classe générique

class Foobar extends AbstractThing<Double> 

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

Alors j'écris ceci:

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

Mais java ne peut pas résoudre le U. À la place, cela fonctionne, mais le second U est en fait redondant car l'AbtractThing définit déjà le type. Alors j'aime m'en débarrasser.

Répondre

26

Vous ne pouvez pas vous en débarrasser. La seconde U n'est pas redondante. Vous voulez que le compilateur interprète le premier U en tant que paramètre de type, mais ce n'est pas le cas. Vous pouvez également avoir écrit ceci:

class EventThing<T extends AbstractThing<Double>> 

Notez que Double dans ce cas est une classe concrète, et non un paramètre de type. Comparez ce qui suit:

class EventThing<T extends AbstractThing<U>> 

Notez que cela a exactement la même forme que la première ligne de code ci-dessus. Comment le compilateur est-il supposé savoir que dans le premier cas, Double est une classe concrète, alors que dans le second cas, U est un paramètre de type?

Le compilateur ne peut pas le savoir, et traite le U comme une classe concrète, tout comme le Double dans la première ligne. La seule façon de laisser le compilateur savoir que U est un paramètre de type est de spécifier comme tel:

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

Il me semble plus comme un élément manquant du compilateur. EDIT: Mais je comprends votre point, merci pour votre réponse. Trop mauvais. Je pense que je vais laisser la caractéristique du trou. –

+4

@Marcel: Je pense que cette réponse explique très clairement pourquoi le compilateur ne peut (et ne devrait pas) tenter de deviner si 'U' est un type réel ou un paramètre de type générique. Java nécessite que chaque paramètre de type générique soit déclaré explicitement pour une bonne raison. Peu importe ce qu'il vous semble, ce n'est pas une "fonctionnalité manquante du compilateur". – ColinD

+1

@ColinD: Je suis d'accord avec Marcel pour dire que cela semble être un élément manquant et que dans son exemple, il semble redondant. Bien que, évidemment, le compilateur doit être informé que U est un argument de type, nous pourrions avoir quelque chose comme: class EventThing >, disant essentiellement: U est un paramètre de type variable, maintenant allez-y et déduisez-le vous-même à des fins de discussion seulement, je suis d'accord c'est moche). De cette façon, il n'y aurait pas de répétition dans le code appelant. – Gilead