J'ai lu des articles écrits sur "ClassCastException", mais je n'ai pas pu me faire une bonne idée à ce sujet. Existe-t-il un bon article ou une brève explication?
Directement des spécifications de l'API pour le ClassCastException
:
Lancé pour indiquer que le code a a tenté de lancer un objet sur un sous-classe dont il n'est pas un exemple.
Ainsi, par exemple, lorsque l’on essaie de convertir un Integer
en String
, String
n’est pas une sous-classe de Integer
, un ClassCastException
est alors généré.
Object i = Integer.valueOf(42);
String s = (String)i; // ClassCastException thrown here.
C'est très simple: si vous essayez de transtyper un objet de classe A en un objet de classe B, et qu'ils ne sont pas compatibles, vous obtenez une exception de transfert de classe.
Pensons à un ensemble de classes.
class A {...}
class B extends A {...}
class C extends A {...}
C'est une exception qui se produit si vous tentez de déclasser une classe, mais en réalité, la classe n'est pas de ce type.
Considérez cette hiérarchie:
Objet -> Animal -> Chien
Vous pourriez avoir une méthode appelée:
public void manipulate(Object o) {
Dog d = (Dog) o;
}
Si appelé avec ce code:
Animal a = new Animal();
manipulate(a);
La compilation est parfaite, mais au moment de l'exécution, vous obtenez une ClassCastException
car o est en fait un animal et non un chien.
Dans les versions ultérieures de Java, vous recevez un avertissement du compilateur sauf si vous procédez comme suit:
Dog d;
if(o instanceof Dog) {
d = (Dog) o;
} else {
//what you need to do if not
}
Considérons un exemple,
class Animal {
public void eat(String str) {
System.out.println("Eating for grass");
}
}
class Goat extends Animal {
public void eat(String str) {
System.out.println("blank");
}
}
class Another extends Goat{
public void eat(String str) {
System.out.println("another");
}
}
public class InheritanceSample {
public static void main(String[] args) {
Animal a = new Animal();
Another t5 = (Another) new Goat();
}
}
À Another t5 = (Another) new Goat()
: vous obtiendrez une ClassCastException
car vous ne pouvez pas créer d'instance de la classe Another
à l'aide de Goat
.
Note: la conversion n'est valide que dans les cas où une classe étend une classe parent et que la classe enfant est convertie en classe parent.
Comment traiter la ClassCastException
:
Comprenez-vous le concept de casting? La conversion est le processus de conversion de type, qui est très courant en Java car il s'agit d'un langage à typage statique. Quelques exemples:
Transforme la chaîne "1" en int -> aucun problème
Transforme la chaîne "abc" en un entier -> déclenche une ClassCastException
Ou pensez à un diagramme de classes avec Animal.class, Dog.class et Cat.class
Animal a = new Dog();
Dog d = (Dog) a; // No problem, the type animal can be casted to a dog, because its a dog.
Cat c = (Dog) a; // Raises class cast exception; you can't cast a dog to a cat.
Vous essayez de traiter un objet comme une instance d'une classe qu'il n'est pas. C'est à peu près analogue à essayer d'appuyer sur une pédale de sourdine sur une guitare (les pianos ont une pédale de sourdine, pas les guitares).
Une exception de conversion de classe est levée par Java lorsque vous essayez de convertir un objet d'un type de données vers un autre.
Java nous permet de convertir des variables d’un type à un autre tant que la conversion a lieu entre des types de données compatibles.
Par exemple, vous pouvez convertir une chaîne en objet et, de la même manière, un objet contenant des valeurs de chaîne peut être converti en chaîne.
Supposons que nous ayons un HashMap contenant un certain nombre d'objets ArrayList.
Si nous écrivons un code comme celui-ci:
String obj = (String) hmp.get(key);
une exception de conversion de classe serait générée, car la valeur renvoyée par la méthode get de la carte de hachage serait une liste Array, mais nous essayons de la convertir en String. Cela provoquerait l'exception.
Un très bon exemple que je peux vous donner pour classcastException en Java est en utilisant "Collection"
List list = new ArrayList();
list.add("Java");
list.add(new Integer(5));
for(Object obj:list) {
String str = (String)obj;
}
Ce code ci-dessus vous donnera une exception ClassCastException au moment de l'exécution. Parce que vous essayez de convertir Integer en String, l’exception sera levée.
Vous pouvez mieux comprendre ClassCastException et la diffusion lorsque vous réalisez que la machine virtuelle Java ne peut pas deviner l'inconnu. Si B est une instance de A, il y a plus de membres de classe et de méthodes sur le tas que d'A. La machine virtuelle Java ne peut pas deviner comment convertir A en B car la cible de mappage est plus grande et la machine virtuelle ne saura pas comment remplir les membres supplémentaires.
Mais si A était une instance de B, cela serait possible car A étant une référence à une instance complète de B, le mappage sera un à un.
Si vous souhaitez trier des objets mais que la classe n'a pas implémenté Comparable ou Comparator, vous obtiendrez ClassCastException Par exemple
class Animal{
int age;
String type;
public Animal(int age, String type){
this.age = age;
this.type = type;
}
}
public class MainCls{
public static void main(String[] args){
Animal[] arr = {new Animal(2, "Her"), new Animal(3,"Car")};
Arrays.sort(arr);
}
}
Au-dessus de la méthode principale lève en dessous de l'exception de transtypage de la classe d'exécution
Exception dans le fil "principal" Java.lang.ClassCastException: com.default.Animal ne peut pas être converti en Java.lang.Comparable.
Une exception Java ClassCastException est une exception qui peut se produire lorsque vous essayez de convertir de manière incorrecte une classe d'un type à un autre.
import Java.util.ArrayList;
import Java.util.Iterator;
import Java.util.List;
public class ClassCastExceptionExample {
public ClassCastExceptionExample() {
List list = new ArrayList();
list.add("one");
list.add("two");
Iterator it = list.iterator();
while (it.hasNext()) {
// intentionally throw a ClassCastException by trying to cast a String to an
// Integer (technically this is casting an Object to an Integer, where the Object
// is really a reference to a String:
Integer i = (Integer)it.next();
}
}
public static void main(String[] args) {
new ClassCastExceptionExample();
}
}
Si vous essayez d’exécuter ce programme Java, vous verrez qu’il générera l’exception ClassCastException suivante:
Exception in thread "main" Java.lang.ClassCastException: Java.lang.String
at ClassCastExceptionExample (ClassCastExceptionExample.Java:15)
at ClassCastExceptionExample.main (ClassCastExceptionExample.Java:19)
La raison pour laquelle une exception est levée ici est que, lorsque je crée mon objet de liste, l'objet que je stocke dans la liste est la chaîne «un», mais que plus tard, lorsque j'essaie d'obtenir cet objet, je me trompe intentionnellement pour le jeter à un entier. Dans la mesure où une chaîne ne peut pas être directement convertie en un entier (un entier n'est pas un type de chaîne), une exception ClassCastException est levée.