Explicación de “ClassCastException” en Java

Leí algunos artículos escritos en “ClassCastException”, pero no pude obtener una buena idea sobre eso. ¿Hay un buen artículo o cuál sería una breve explicación?

Directamente de las especificaciones API para ClassCastException :

Lanzado para indicar que el código ha intentado lanzar un objeto a una subclase de la cual no es una instancia.

Entonces, por ejemplo, cuando uno trata de convertir un Integer a una String , String no es una subclase de Integer , por lo que se lanzará una ClassCastException .

 Object i = Integer.valueOf(42); String s = (String)i; // ClassCastException thrown here. 

Es bastante simple: si intentas convertir un objeto de clase A en un objeto de clase B y no son compatibles, obtienes una excepción de clase.

Pensemos en una colección de clases.

 class A {...} class B extends A {...} class C extends A {...} 
  1. Puede enviar cualquiera de estas cosas a Object, porque todas las clases de Java heredan de Object.
  2. Puedes convertir B o C en A, porque ambos son “tipos de” A
  3. Puede convertir una referencia a un objeto A en B solo si el objeto real es un B.
  4. No puedes lanzar una B a una C a pesar de que ambas son A’s.

Es una excepción que ocurre si intenta bajar una clase, pero de hecho la clase no es de ese tipo.

Considera esta jerarquía:

Objeto -> Animal -> Perro

Es posible que tenga un método llamado:

  public void manipulate(Object o) { Dog d = (Dog) o; } 

Si se llama con este código:

  Animal a = new Animal(); manipulate(a); 

Se comstackrá muy bien, pero en tiempo de ejecución obtendrás una ClassCastException porque o era de hecho un Animal, no un Perro.

En las versiones posteriores de Java, obtienes una advertencia de comstackción a menos que lo hagas:

  Dog d; if(o instanceof Dog) { d = (Dog) o; } else { //what you need to do if not } 

Considera un ejemplo,

 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(); } } 

At Another t5 = (Another) new Goat() : obtendrá una ClassCastException porque no puede crear una instancia de la clase Another usando Goat .

Nota : La conversión es válida solo en los casos en que una clase extiende una clase principal y la clase secundaria se convierte en su clase principal.

Cómo lidiar con ClassCastException :

  1. Tenga cuidado al intentar convertir un objeto de una clase en otra clase. Asegúrese de que el nuevo tipo pertenece a una de sus clases principales.
  2. Puede evitar ClassCastException utilizando Generics, ya que Generics proporciona comprobaciones de tiempo de comstackción y se puede usar para desarrollar aplicaciones de tipo seguro.

Fuente de la nota y el rest

¿Entiendes el concepto de casting? Casting es el proceso de conversión de tipo, que es muy común en Java porque es un lenguaje estáticamente tipado. Algunos ejemplos:

Transmite la cadena “1” a un int -> no hay problema

Emitir la cadena “abc” a un int -> genera una ClassCastException

O piense en un diagtwig de clases con Animal.class, Dog.class y 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. 

Está tratando de tratar un objeto como una instancia de una clase que no lo es. Es más o menos análogo intentar presionar el pedal de amortiguación en una guitarra (los pianos tienen pedales amortiguadores, las guitarras no).

Java emite una excepción de conversión de clase cuando intenta convertir un Objeto de un tipo de datos a otro.

Java nos permite convertir variables de un tipo a otro siempre que la conversión ocurra entre tipos de datos compatibles.

Por ejemplo, puede convertir una Cadena como un Objeto y, de forma similar, un Objeto que contiene valores de Cadena se puede convertir a una Cadena.

Ejemplo

Supongamos que tenemos un HashMap que contiene una cantidad de objetos ArrayList.

Si escribimos código como este:

 String obj = (String) hmp.get(key); 

arrojaría una excepción de lanzamiento de clase, porque el valor devuelto por el método get del mapa hash sería una lista de Array, pero estamos intentando convertirlo en una Cadena. Esto causaría la excepción.

Un muy buen ejemplo que puedo darte para classcastException en Java es al usar “Colección”

 List list = new ArrayList(); list.add("Java"); list.add(new Integer(5)); for(Object obj:list) { String str = (String)obj; } 

Este código anterior le dará ClassCastException en tiempo de ejecución. Como está intentando convertir Entero a Cadena, arrojará la excepción.

Puede comprender mejor ClassCastException y casting una vez que se da cuenta de que la JVM no puede adivinar lo desconocido. Si B es una instancia de A, tiene más miembros de clase y métodos en el montón que A. La JVM no puede adivinar cómo convertir A a B ya que el destino de la asignación es más grande y la JVM no sabrá cómo llenar los miembros adicionales.

Pero si A fuera una instancia de B, sería posible, porque A es una referencia a una instancia completa de B, por lo que la asignación será uno a uno.

Una Java ClassCastException es una excepción que puede ocurrir cuando intenta convertir incorrectamente una clase de un tipo a otro.

 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 intenta ejecutar este progtwig Java, verá que generará la siguiente ClassCastException:

 Exception in thread "main" java.lang.ClassCastException: java.lang.String at ClassCastExceptionExample (ClassCastExceptionExample.java:15) at ClassCastExceptionExample.main (ClassCastExceptionExample.java:19) 

La razón por la cual se lanza una excepción aquí es que cuando estoy creando mi objeto de lista, el objeto que almaceno en la lista es el “uno” de Cadena, pero luego, cuando bash sacar este objeto, cometo un error intentándolo intencionalmente para convertirlo en un Entero. Debido a que una Cadena no se puede convertir directamente a un Entero, un Entero no es un tipo de Cadena, se lanza una ClassCastException.