2010-09-28 7 views
0

Les classes que je traite sont les suivants,erreur capture Wildcard

public interface One{ 
    public Two get(); 
} 

public class Foo{...} 
public class Bar extends Foo{...} 

public abstract class Parent<T extends Foo> implements One {...} 

public abstract class Child<T extends Foo> extends Parent<T> 

J'ai une méthode statique qui retourne un objet enfant donné un objet Foo,

public static Child<? extends Foo> get(Foo f){...} 

Cette méthode renvoie un enfant construit à partir d'un objet Foo ou Bar. Le code qui jette l'erreur est-ce,

Foo f = new Foo(); 
Child<? extends Foo> child = O.get(f); 
Two t = S.apply(child); 

La méthode apply,

public Two apply(One o){...}; 

L'erreur qui est jeté est,

apply(One) in S cannot be applied to (Child<capture#123 of ?>) 

Ma solution actuelle à ce problème est de changer le code à ceci,

Foo f = new Foo(); 
Child<? extends Foo> child = O.get(f); 
Object o = child; 
One one = (One)o; 
Two t = S.apply(one); 

Cela résout l'erreur, je ne sais pas pourquoi le casting explicite à l'objet doit être là, mais il est là.

Quelqu'un peut-il me dire s'il est possible de modifier le code afin que les conversions ne soient pas nécessaires pour que cela fonctionne?

+2

Le code que vous avez donné fonctionne pour moi sans la solution de contournement donnée lors de la compilation à la fois pour 1.5 et 1.6. C'est presque comme si Child ne savait pas que Parent implémente One. – ILMTitan

+0

Ouais, je voudrais nettoyer et reconstruire. Ou si vous ne nous donnez pas un exemple qui présente le problème, donnez-nous un exemple qui montre le problème. –

+0

C'est la compilation nocturne qui lance l'erreur, donc je ne suis pas tout à fait sûr quels sont les paramètres du compilateur exact. J'essaie de trouver un moyen de mieux le reproduire maintenant. – Andrew

Répondre

0

Je pense que je peux vous le dire. Malheureusement, il vous manque beaucoup de code, mais j'ai déjà vu ce genre de chose et je sais comment y remédier. Le résoudre implique une syntaxe pas souvent vu de Java.

Tout d'abord, vous devez taper votre méthode statique, comme ceci:

public static <T extends Foo> Child<T> get(Foo f){...} 

Bien que ne pas avoir vu le code, il est possible que, étant donné que le changement, que cela fonctionne:

Two t = S.apply(child); 

Toutefois, si vous avez besoin, vous pouvez fournir le type si vous avez besoin, comme ceci:

Two t = S.<Two>apply(child); // Cool huh? 

ce s yntax est comment vous forcer le type pour une méthode statique typée.

Je ne suis pas sûr si ce code exact fonctionnera pour vous, parce que vous n'avez pas fourni assez de code, mais la solution sera assez proche de ceci si ce n'est pas le cas.

Si cela ne fonctionne pas, postez tous les du code que vous avez et je vais essayer de le faire fonctionner pour vous.

+0

La méthode statique 'get' n'a pas la même signification que la méthode originale. Ici, l'appelant peut décider quel est le type de paramètre, alors qu'avec 'Child 'la méthode elle-même peut le décider. Je pense que l'on veut réellement public static Child obtenir (T f) {...} '. –

+0

En outre, la méthode 'apply' semble être non générique, vous ne pouvez pas fournir de paramètre de type ici. –

+0

Si vous revenez et lisez mon post, vous verrez que cette approche nécessite deux étapes - la première est de paramétrer la méthode - voir l'étape 1. de ma réponse – Bohemian