Question

J'ai le concept de NodeType s et Node s. Un createInstance() est un groupe de métadonnées à partir desquelles vous pouvez créer public Thing createInstance() des instances (un peu comme toute la relation Classe / Objet).

J'ai différentes @SuppressWarnings("unchecked") implémentations et diverses implémentations de nœuds.

Dans mon AbstractNodeType (niveau supérieur pour les NodeTypes), j'ai une méthode abstraite <=> qui, une fois implémentée par la sous-classe, crée l'instance de nœud appropriée:

public abstract class AbstractNodeType {
  // ..

  public abstract <T extends AbstractNode> T createInstance();
}

Dans mes <=> implémentations, j'implémente la méthode comme suit:

public class ThingType {
  // ..

  public Thing createInstance() {
    return new Thing(/* .. */);
  }
}

// FYI
public class Thing extends AbstractNode { /* .. */ }

Tout cela est bien beau, mais <=> crée un avertissement sur la sécurité du type. Plus précisément:

  

Type safety: Le type de retour Chose pour   createInstance () du type   ThingType nécessite une conversion non contrôlée   se conformer à T du type   AbstractNodeType

Qu'est-ce que je fais de mal pour provoquer un tel avertissement?

Comment puis-je reformuler mon code pour résoudre ce problème?

<=> n'est pas bon, je souhaite résoudre ce problème en le codant correctement, sans ignorer le problème!

Était-ce utile?

La solution

Vous pouvez simplement remplacer <T extends AbstractNode> T par AbstractNode grâce à la magie des retours de covariant Java 5 ajouté de l'aide, mais il n'a pas reçu le pub qu'il méritait.

Autres conseils

Deux façons:

(a) N'utilisez pas de génériques. Ce n'est probablement pas nécessaire dans ce cas. (Bien que cela dépende du code que vous n'avez pas montré.)

(b) Générez AbstractNodeType comme suit:

public abstract class AbstractNodeType<T extends AbstractNode> {
  public abstract T createInstance();
}
public class ThingType<Thing> {
  public Thing createInstance() {
    return new Thing(...);
  }
}

Quelque chose comme ça devrait marcher:

interface Node{
}
interface NodeType<T extends Node>{
    T createInstance();
}
class Thing implements Node{}
class ThingType implements NodeType<Thing>{
    public Thing createInstance() {
        return new Thing();
    }
}
class UberThing extends Thing{}
class UberThingType extends ThingType{
    @Override
    public UberThing createInstance() {
        return new UberThing();
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top