Объяснение "ClassCastException" в Java
Я читал некоторые статьи, написанные на "ClassCastException", но я не мог получить хорошее представление об этом. Есть ли хорошая статья или что было бы краткое объяснение?
11 ответов:
прямо из спецификаций API для
ClassCastException
:брошенный, чтобы указать, что код попытка привести объект к a подкласс которого он не является пример.
так, например, когда кто-то пытается бросить
Integer
доString
,String
не является подклассомInteger
, Так aClassCastException
будет брошен.Object i = Integer.valueOf(42); String s = (String)i; // ClassCastException thrown here.
это действительно довольно просто: если вы пытаетесь типизировать объект класса A в объект класса B, и они несовместимы, вы получаете исключение приведения класса.
давайте подумаем о коллекции классов.
class A {...} class B extends A {...} class C extends A {...}
- вы можете привести любую из этих вещей к объекту, потому что все классы Java наследуются от объекта.
- вы можете привести либо B, либо C К A, потому что они оба "виды" A
- вы можете привести ссылку на объект A к Б только если реальный объект-это B.
- вы не можете бросить 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 -> нет проблем
приведение строки " abc " к int -> вызывает ClassCastException
или подумайте о диаграмме классов с животными.класс, собака.класс и кошка.класс
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);
это вызовет исключение приведения класса, потому что значение, возвращаемое методом 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)
причина исключения здесь заключается в том, что когда я создаю свой объект списка, объект, который я храню в списке, является строкой "один", но позже, когда я пытаюсь получить этот объект, я намеренно делаю ошибка, пытаясь привести его к целому числу. Поскольку строка не может быть непосредственно приведена к целому числу-целое число не является типом строки-создается исключение 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); } }
выше основного метода будет бросать ниже класса выполнения cast exception
исключение в потоке" main " java.ленг.ClassCastException: com.по умолчанию.Животное не может быть приведено к java.ленг.Сравним