Explicação de “ClassCastException” em Java

Eu li alguns artigos escritos em “ClassCastException”, mas não consegui ter uma boa idéia sobre isso. Existe um bom artigo ou o que seria uma breve explicação?

Diretamente das especificações da API para o ClassCastException :

Lançada para indicar que o código tentou converter um object em uma subclass da qual não é uma instância.

Então, por exemplo, quando se tenta converter um Integer em um String , String não é uma subclass de Integer , então um ClassCastException será lançado.

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

É realmente muito simples: se você está tentando converter um object da class A em um object da class B, e eles não são compatíveis, você recebe uma exceção de conversão de class.

Vamos pensar em uma coleção de classs.

 class A {...} class B extends A {...} class C extends A {...} 
  1. Você pode converter qualquer uma dessas coisas para Object, porque todas as classs Java herdam de Object.
  2. Você pode converter B ou C para A, porque ambos são “tipos de” A
  3. Você pode converter uma referência a um object A para B somente se o object real for um B.
  4. Você não pode lançar um B para um C, embora ambos sejam A’s.

É uma exceção que ocorre se você tentar abater uma class, mas na verdade a class não é desse tipo.

Considere esta hierarquia:

Objeto -> Animal -> Cachorro

Você pode ter um método chamado:

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

Se chamado com este código:

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

Ele irá compilar muito bem, mas em tempo de execução você receberá um ClassCastException porque o era de fato um Animal, não um Cão.

Em versões posteriores do Java, você recebe um aviso do compilador, a menos que você faça:

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

Considere um exemplo

 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() : você receberá um ClassCastException porque não pode criar uma instância da class Another usando o Goat .

Nota : A conversão é válida apenas nos casos em que uma class estende uma class pai e a class filha é convertida em sua class pai.

Como lidar com o ClassCastException :

  1. Tenha cuidado ao tentar converter um object de uma class em outra class. Assegure-se de que o novo tipo pertença a uma de suas classs pai.
  2. Você pode impedir o ClassCastException usando Genéricos, porque os Genéricos fornecem verificações de tempo de compilation e podem ser usados ​​para desenvolver aplicativos seguros contra tipos.

Fonte da nota e o resto

Você entende o conceito de fundição? Casting é o processo de conversão de tipos, que é muito comum em Java, porque é uma linguagem tipada estaticamente. Alguns exemplos:

Transmita a string “1” para um int -> sem problemas

Transmita a string “abc” para um int -> gera um ClassCastException

Ou pense em um diagrama de classs com Animal.class, Dog.class e 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. 

Você está tentando tratar um object como uma instância de uma class que não é. É mais ou menos semelhante a tentar pressionar o pedal de sustentação em uma guitarra (os pianos têm pedais de sustentação, as guitarras não).

Uma exceção de conversão de class é lançada por Java quando você tenta converter um object de um tipo de dados em outro.

Java nos permite converter variables ​​de um tipo para outro, desde que o casting ocorra entre tipos de dados compatíveis.

Por exemplo, você pode converter uma String como um Objeto e, da mesma forma, um Objeto que contém valores String pode ser convertido em uma String.

Exemplo

Vamos supor que temos um HashMap que contém vários objects ArrayList.

Se escrevermos código assim:

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

ele lançaria uma exceção de conversão de class, porque o valor retornado pelo método get do mapa de hash seria uma lista de Array, mas estamos tentando convertê-lo em uma String. Isso causaria a exceção.

Um bom exemplo que posso dar a você para classcastException em Java é usando “Collection”

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

Este código acima lhe dará ClassCastException em tempo de execução. Porque você está tentando converter Integer para String, isso lançará a exceção.

Você pode entender melhor o ClassCastException e o casting quando perceber que a JVM não pode adivinhar o desconhecido. Se B for uma instância de A, ela terá mais membros de class e methods no heap do que A. A JVM não pode adivinhar como converter A para B, já que o destino de mapeamento é maior e a JVM não saberá como preencher os membros adicionais.

Mas se A fosse uma instância de B, seria possível, porque A é uma referência a uma instância completa de B, portanto, o mapeamento será um para um.

Um Java ClassCastException é uma exceção que pode ocorrer quando você tenta converter uma class incorretamente de um tipo para outro.

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

Se você tentar executar este programa Java, verá que ele lançará o seguinte ClassCastException:

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

A razão pela qual uma exceção é lançada aqui é que quando eu estou criando meu object de lista, o object que eu armazeno na lista é String “um”, mas depois quando eu tento tirar esse object eu intencionalmente cometo um erro tentando para lançá-lo para um Integer. Como uma String não pode ser convertida diretamente em um Integer – um Integer não é um tipo de String – uma ClassCastException é lançada.