J'ai rencontré un comportement de génériques en Java que je ne peux pas comprendre complètement (avec mon arrière-plan .net). S'il vous plaît dites-moi pourquoi je ne reçois pas la classecast Obtenez, d'ailleurs, dans l'idée que je vois Temp comme string code> après la cession et la valeur de "crack !!!" code>. Aussi, comment pourrais-je avoir cette catégorie de ClasscastException? J'utilise JDK 1.7.0_07 sur Windows 7 x64. P> P>
7 Réponses :
Ceci est dû à Voici un lien sur Effacement de type p>
Le seul moyen de réellement obtenir vraiment le Type-Erasure Code>. Cela signifie que, dans Java, tous les génériques sont réduits à objet code> au moment de l'exécution. Vous avez donc lancé votre chaîne code> à objet code> qui est totalement fin. Et puisque Tostring code> est implémenté sur objet code>, à nouveau aucune exception. P>
classcastexception code> est de passer une instance de Classe MyClass.Isinstance (Arg ) code> et lancer une exception si false code> p>
Est-ce vraiment le "seul moyen"? Nitegazer2003 a mentionné ce qui me frappe comme une approche plus propre,
Ce que je veux dire par "le seul moyen", c'est qu'un générique n'a pas le type défini au moment de l'exécution. Par conséquent, si le comportement souhaité est de lancer une classeCastException, le type doit être explicitement fourni au générique en passant dans une instance de classe numéro code> n'est valide que si c'est la condition. Il n'y a rien dans la mise en œuvre générique qui suggérerait qu'il ne devrait fonctionner que pour des instances de numéro code>.
La raison pour laquelle vous n'obtenez pas une exception de casting de classe est que les génériques Java sont implémentées par l'effacement de type. Contrairement aux génériques de .NET qui nécessitaient des modifications importantes sur CLS, les génériques Java sont entièrement traitées dans la compilation. Au moment de l'exécution, la distribution à t code> est ignorée. Afin de vérifier le type à l'exécution, vous devez stocker class public class TestGeneric<T>
{
private Class<T> genClass;
public TestGeneric(Class<T> t) {genClass = t;}
public void get (Object arg)
{
if (!genClass.isInstance(arg)) {
throw new ClassCastException();
}
T temp = (T) arg;
System.out.println(temp.toString());
return;
}
}
TestGeneric<Integer> tg = new TestGeneric<Integer>(Integer.class);
tg.get("Bang!!!"); // Now that's a real Bang!!!
Avez-vous vraiment "besoin" ou y a-t-il une meilleure "meilleure pratique"? J'aime l'approche Nitegazer2003 mentionnée,
Bien que vous ayez répondu à sa question correctement, mais il est question de savoir comment utiliser le générique correctement et pourquoi avez-vous besoin d'un "retour" à la fin de rien? et ressemble à des voies plus compliquées que nécessaire. J'ai ajouté ma réponse de la façon dont vous devriez utiliser générique.
Le type Vous n'avez appelé aucun La raison en est que, à l'exécution, vous ne verrez pas les paramètres de type BeaSe of Erasure de type . P>
Le point est qu'après la compilation de votre code, vous ne pourrez plus pouvoir voir les paramètres de type générique car ils sont effacés. P>
Il y a une autre question ici qui explique la classification de la classe exception: Explication < / p>
Dans ce code, vous pouvez voir que l'utilisateur a essayé de jeter explicitement à Vous pouvez donc appeler cela une lacune de Java par rapport à C #. P> INTEGER code> a une méthode tostring code>. En fait, chaque objet code> a cette méthode afin que classcastexception code> ne se produise pas. P>
chaîne code> -Pécurifique sur votre objet, aucune exception n'est donc produite. p>
String code> pas sur un paramètre générique. P>
-1: TOSTRING code> n'est pas automatiquement appelé lorsque vous lancez quelque chose, et cette distribution est l'autre direction de toute façon.
Je n'ai pas dit que cela est automatiquement appelé.
Après les modifications, votre réponse ne semble pas référencer le tout, ce qui est approprié, car il n'est pas pertinent. Si j'avais réellement évité, je l'aurais rétracté maintenant, mais cela semble que mon bowvote n'a pas pris.
"Vous n'avez appelé aucune méthode spécifique à la chaîne sur votre objet" mais en fait, il n'est pas possible d'appeler une méthode spécifique à la chaîne sur cette référence, car elle est de type t code>, un paramètre de type qui peut être n'importe quel type de référence.
C'est parce que le type générique T n'a pas de limites définies, il est donc traité comme un objet. La coulée de quelque chose à t ne provoquera pas de Toutefois, si votre définition de classe était clascastexception code> dans ce cas. p>
CLASSE PUBLIC CLASSE TESTGÉRERIERRERIERRERIERRERIQUE
+1 Pour répondre à la question de l'OP sur la façon de recevoir une exception classique.
Rappelez-vous toujours que les génériques de Java sont des entités de temps compilation. Cela n'a rien à faire au moment de l'exécution. Laissez-moi démo votre code OQN à vous.
Crack!!! class java.lang.String
C'est un exercice instructif de penser à ce que le code non générique que le code générique est "effacé à" ressemble à:
Réponse géniale! Un exemple concret de quelle effacement fait effectivement.
Si vous le faites de cette façon, vous n'avez même pas besoin de vérifier la classeCastException et que cela ne sera même pas capable de compiler.