Объяснение "ClassCastException" в Java
Я читал некоторые статьи, написанные на "ClassCastException", но я не мог получить хорошее представление об этом. Есть ли хорошая статья или то, что было бы кратким объяснением?
11 ответов
прямо из спецификаций API для ClassCastException
:
брошенный, чтобы указать, что код попытка бросить объект в подкласс, к которому он не относится пример.
так, например, когда один пытается бросить Integer
до String
, String
не является подклассом Integer
, Так что ClassCastException
будет брошен.
Object i = Integer.valueOf(42);
String s = (String)i; // ClassCastException thrown here.
это действительно довольно просто: если вы пытаетесь типизировать объект класса A в объект класса B, и они несовместимы, вы получаете исключение класса cast.
давайте подумаем о коллекции классов.
class A {...}
class B extends A {...}
class C extends A {...}
- вы можете привести любую из этих вещей к объекту, потому что все классы Java наследуются от Object.
- вы можете бросить либо B, либо C В A, потому что они оба "виды" a
- вы можете привести ссылку на объект A К Б только если реальный объект является Б.
- вы не можете бросить B В C, даже если они оба A.
это исключение, которое возникает, если вы пытаетесь понизить класс, но на самом деле класс не такого типа.
рассмотрим эту наследственность:
Объект -> Животные -> Собаки
у вас может быть метод под названием:
public void manipulate(Object o) {
Dog d = (Dog) o;
}
если вызывается с этим кодом:
Animal a = new Animal();
manipulate(a);
Он будет компилироваться нормально, но во время выполнения, вы получите ClassCastException
потому что о на самом деле был животным, а не собакой.
в более поздних версиях Java вы получаете предупреждение компилятора, если вы не делаете:
Dog d;
if(o instanceof Dog) {
d = (Dog) o;
} else {
//what you need to do if not
}
Рассмотрим пример
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()
вы получаете ClassCastException
потому что вы не можете создать экземпляр Another
класс с помощью Goat
.
Примечание: преобразование действует только в тех случаях, когда класс расширяет родительский класс и дочерний класс будет преобразован в своего родительского класса.
как бороться с ClassCastException
:
- будьте осторожны при попытке привести объект класса в другой класс. Обеспечить, чтобы новый тип принадлежит к одному из родительских классов.
- вы можете предотвратить ClassCastException с помощью дженериков, поскольку дженерики обеспечивают проверку времени компиляции и могут использоваться для разработки приложений, безопасных для типов.
вы понимаете концепцию кастинга? Литье-это процесс преобразования типов, который в Java очень распространен, потому что его статически типизированный язык. Некоторые примеры:
приведите строку " 1 " к int -> no problem
приведите строку " abc " к int -> вызывает ClassCastException
или подумайте о диаграмме классов с Animal.класс, пес.класс и кошка.класс!--2-->
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.
вы пытаетесь рассматривать объект как экземпляр класса, что это не так. Это примерно аналогично попытке нажать педаль демпфера на гитаре (у пианино есть педали демпфера, у гитар нет).
исключение приведения класса создается Java при попытке приведения объекта одного типа данных к другому.
Java позволяет нам передавать переменные одного типа другому, пока кастинг происходит между совместимыми типами данных.
например, вы можете привести строку в качестве объекта, и аналогично объект, содержащий строковые значения, может быть приведен к строке.
пример
предположим, что у нас есть HashMap, который содержит ряд ArrayList объекты.
Если мы напишем такой код:
String obj = (String) hmp.get(key);
это вызовет исключение cast класса, потому что значение, возвращаемое методом get хэш-карты, будет списком массивов, но мы пытаемся привести его к строке. Это вызвало бы исключение.
очень хороший пример, который я могу дать вам для classcastException в Java, при использовании "Collection"
List list = new ArrayList();
list.add("Java");
list.add(new Integer(5));
for(Object obj:list) {
String str = (String)obj;
}
этот код выше даст вам ClassCastException во время выполнения. Поскольку вы пытаетесь привести целое число к строке, это вызовет исключение.
вы можете лучше понять ClassCastException и кастинг, как только поймете, что JVM не может угадать неизвестное. Если b является экземпляром A, он имеет больше членов класса и методов в куче, чем A. JVM не может догадаться, как привести A к B, так как цель сопоставления больше, и JVM не будет знать, как заполнить дополнительные члены.
но если бы A был экземпляром B, это было бы возможно, потому что A является ссылкой на полный экземпляр B, поэтому отображение будет один на один.
исключение Java ClassCastException является исключением, которое может возникнуть при попытке неправильно преобразовать класс из одного типа в другой.
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();
}
}
Если вы попытаетесь запустить эту программу Java, вы увидите, что она бросит следующее исключение ClassCastException:
Exception in thread "main" java.lang.ClassCastException: java.lang.String
at ClassCastExceptionExample (ClassCastExceptionExample.java:15)
at ClassCastExceptionExample.main (ClassCastExceptionExample.java:19)
причина, по которой здесь возникает исключение, заключается в том, что при создании объекта list объект, который я храню в списке, является строкой "one", но затем, когда я пытаюсь получить этот объект, я намеренно делаю ошибка в попытке привести его к целому числу. Поскольку строка не может быть непосредственно приведена к целому числу-целое число не является типом строки-создается исключение ClassCastException.
Если вы хотите сортировать объекты, но если класс не реализовал Comparable или Comparator, то вы получите ClassCastException Например
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);
}
}
выше main метод будет бросать ниже класса выполнения cast exception
исключение в потоке" main " java.ленг.ClassCastException: com.по умолчанию.Животное не может быть брошено на java.ленг.Сравнимый