J'essaie de convertir un objet dans ma classe Action, mais un avertissement est généré:
Type safety: Unchecked cast from Object to Action<ClientInterface>
Action<ClientInterface> action = null;
try {
Object o = c.newInstance();
if (o instanceof Action<?>) {
action = (Action<ClientInterface>) o;
} else {
// TODO 2 Auto-generated catch block
throw new InstantiationException();
}
[...]
Merci pour toute aide
Oui, c’est une conséquence naturelle de type gomme . Si o
est en fait une instance de Action<String>
qui ne sera pas interceptée par le casting, vous ne verrez le problème que lorsque vous essayez de l'utiliser, en passant une ClientInterface
à la place d'une chaîne.
Vous pouvez vous débarrasser de l'avertissement en utilisant:
@SuppressWarnings("unchecked")
comme une annotation de fonction, mais vous ne pouvez pas résoudre facilement le problème sous-jacent :(
Comme d'habitude, Jon Skeet a raison.
Pour élaborer sur la partie difficile de sa réponse:
Donné
class ClientAction implements Action<ClientInterface> {}
Tu peux écrire:
Class<? extends Action<ClientInterface>> c = ClientAction.class;
Action<ClientInterface> action = c.newInstance();
Cela élimine à la fois la conversion et l'avertissement, au prix de l'introduction d'un type non générique afin que vous puissiez utiliser .class
pour obtenir un objet Class
suffisamment typé.
L'avertissement signifie que le compilateur ne peut pas garantir la sécurité du type même si le transtypage fonctionne correctement à l'exécution. En raison de l'effacement, au moment de l'exécution, le casting est simplement un casting pour Action. Il est possible que la classe générique sous-jacente ne soit pas de type ClientInterface comme prévu. Dans ce cas, le problème apparaîtra plus tard (peut-être même beaucoup plus tard) sous forme d'exception ClassCastException.
Dans ce cas spécifique, je recommande de supprimer cet avertissement spécifique à l'aide de la directive de compilation suivante:
@SuppressWarnings("unchecked")
Ne t'inquiète pas pour. C'est parce que le compilateur Java n'a aucun moyen de savoir quel est le type réel de l'objet.
Vous avez perdu les informations de type en raison de l'effacement (c'est-à-dire que les types paramétrés ont été effacés), d'où l'avertissement. Vous ne pouvez rien y faire, à part nettoyer le code qui l'entoure afin que les génériques soient utilisés plus fréquemment, afin que vous puissiez transmettre les informations de type génériques et éviter toute diffusion.
Ceci est une baisse. C'est le casting dynamique où le compilateur n'a aucune idée de l'objet réel pointé par la référence.
Vous recevez cet avertissement, car le type cible de la conversion Action<ClientInterface>
est un type paramétré et le compilateur ne peut pas garantir que l'objet en cours de conversion est du même type.
Si vous ne souhaitez pas supprimer cet avertissement et que vous ne vous souciez pas du paramètre type, vous pouvez modifier le code en utilisant des caractères génériques:
Action<?> action = null;
try {
Object o = c.newInstance();
if (o instanceof Action<?>) {
action = (Action<?>) o;
} else {
// TODO 2 Auto-generated catch block
throw new InstantiationException();
}
[...]
Ceci est beaucoup plus sûr car la instanceof
ne peut pas vérifier que o
est un objet de Action<ClientInterface>
, il vérifie simplement si o
est un objet de Action
car les informations de type génériques suivantes seront effacées à l'exécution.