Dynamique de la coulée en Java
Avant de me reproche de ne pas faire mes devoirs, j'ai été incapable de trouver des indices sur la multitude de questions sur Java génériques et de la dynamique de la coulée.
Le type Scalaire est défini comme suit:
public class Scalar <T extends Number> {
public final String name;
T value;
...
public T getValue() {
return value;
}
public void setValue(T val) {
this.value = val;
}
}
Je voudrais avoir une méthode qui ressemble à ceci:
public void evilSetter(V val) {
this.value = (T) val;
}
Sûr, c'est généralement déconseillée. La raison pour laquelle je tiens une telle méthode est parce que j'ai une collection de Scalaires dont les valeurs que j'aimerais changer plus tard. Cependant, une fois qu'ils vont dans la collection, leurs paramètres de type générique ne sont plus accessibles. Donc, même si je veux faire une affectation qui est parfaitement valide au moment de l'exécution, il n'y a aucun moyen de savoir que ça va être valide au moment de la compilation, avec ou sans les génériques.
Map<String, Scalar<? extends Number>> scalars = ...;
Scalar<? extends Number> scalar = scalars.get("someId");
//None of this can work
scalar.value = ...
scalar.setValue(...)
Alors, comment puis-je mettre en œuvre un contrôle de fonte et la méthode de jeu?
public <V extends Number> void castAndSet(V val) {
//One possibility
if (this.value.getClass().isAssignableFrom(val.getClass()) {
//Some cast code here
}
//Another
if (this.value.getClass().isInstanceOf(val) {
//Some cast code here
}
//What should the cast line be?
//It can't be:
this.value = this.value.getClass().cast(val);
//Because this.value.getClass() is of type Class<?>, not Class<T>
}
Donc je suis parti avec l'aide de
this.value = (T) val;
et attraper une ClassCastException?
Dans ma frustration, j'ai été tenté de le faire, mais j'aimerais quitter l'établissement pour, disons, un RichScalar qui est des unités.
OriginalL'auteur dgorur | 2010-10-15
Vous devez vous connecter pour publier un commentaire.
Vous avez:
C'est probablement va être un problème, sauf si vous pouvez être certain
value
ne sera jamais nulle.Vous avez aussi:
Cela ne sera jeté à l'
Number
et de ne pasT
car sous le capotT
est juste unNumber
en raison de type-erasure. Donc sivalue
est unDouble
etval
est unInteger
, aucune exception n'est levée.Si vous souhaitez effectuer une vérifié de fonte, vous devez avoir le bon
Class<T>
objet. Cela signifie que vous devriez être en train de passerClass<T>
dans le constructeur de votre objet. (À moins que vous pouvez être sûrvalue
n'est jamais null, auquel cas vous pouvez aller avec votre première idée.) Une fois que vous avez cet objet (stockées dans un champ), vous pouvez effectuer les bagages cast:le casting original extrait de code n'a pas été spécifiée. Vous avez juste "// cast code ici". doit:
value = value.getClass().cast(val);
, qui ne compile.J'ai mis le casting du code au bas de l'extrait de code, et la raison pour laquelle il ne serait pas compiler pour moi. Intéressant qu'il n'a compiler pour vous! Pourrait-il être javac version ou quelque chose? Eclipse me dit: incompatibilité de Type: impossible de convertir de la capture n ° 1-de ? s'étend Nombre de T. C'est comment je suis arrivé à la raison que je fournis dans l'extrait de code...
Qu'est-ce que l'erreur de compilation?
Naufragé.java:16: incompatible types : capture#556 ? s'étend java.lang.Nombre requis: valeur T = valeur.getClass().cast(val); ^ 1 error
OriginalL'auteur Kirk Woll