Я прочитав кілька статей, написаних на "ClassCastException", але не міг отримати хорошої ідеї щодо цього. Чи є хороша стаття або що було б коротким поясненням?
Я прочитав кілька статей, написаних на "ClassCastException", але не міг отримати хорошої ідеї щодо цього. Чи є хороша стаття або що було б коротким поясненням?
Відповіді:
Прямо зі специфікацій API для ClassCastException
:
Кидається, щоб вказати, що код намагався передати об'єкт підкласу, екземпляром якого він не є.
Так, наприклад, коли хтось намагається кинути Integer
a String
, String
не є підкласом Integer
, тому a ClassCastException
буде кинуто.
Object i = Integer.valueOf(42);
String s = (String)i; // ClassCastException thrown here.
Це насправді досить просто: якщо ви намагаєтесь ввести об’єкт класу A в об’єкт класу B, але вони не сумісні, ви отримаєте виняток класу класу.
Давайте подумаємо про колекцію занять.
class A {...}
class B extends A {...}
class C extends A {...}
Це виняток, який виникає, якщо ви намагаєтесь знизити клас, але насправді клас не такого типу.
Розглянемо цю ієрархію:
Об'єкт -> Тварина -> Собака
У вас може бути метод, який називається:
public void manipulate(Object o) {
Dog d = (Dog) o;
}
Якщо викликати з цим кодом:
Animal a = new Animal();
manipulate(a);
Він скомпілюється дуже добре, але під час виконання ви отримаєте, ClassCastException
тому що o насправді був твариною, а не собакою.
У пізніших версіях 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
:
Ви намагаєтеся розглядати об'єкт як екземпляр класу, яким він не є. Це приблизно аналогічно спробі натиснути на гітару на педалі заслінки (піаніно має педалі заслінки, гітари - ні).
Ви розумієте концепцію кастингу? Кастинг - це процес перетворення типів, який у Java дуже поширений, оскільки це статично набрана мова. Кілька прикладів:
Передайте рядок "1" в int -> немає проблем
Передайте рядок "abc" на int -> викликає ClassCastException
Або придумайте схему класів з Animal.class, Dog.class та 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.
Cat c = (Dog) a
не спричинить ClassCastException
помилку, але помилка компілятора ( невідповідність типу )
Виняток класу для класу передається Java, коли ви намагаєтесь передати об’єкт одного типу даних іншому.
Java дозволяє передавати змінні одного типу іншому, доки відбувається перекидання між сумісними типами даних.
Наприклад, ви можете передати рядок як об'єкт, а також об'єкт, що містить значення рядка, можна передати в рядок.
Припустимо, у нас є HashMap, що містить ряд об’єктів ArrayList.
Якщо ми пишемо код так:
String obj = (String) hmp.get(key);
це викине виняток класу для класу, оскільки значення, яке повертається методом get на карті хешу, буде списком масиву, але ми намагаємося передати його в рядок. Це спричинило б виняток.
Дуже хороший приклад, який я можу надати вам для classcastException на Java, - це використання "Колекції"
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)
Причина, по якій тут виникає виняток, полягає в тому, що коли я створюю свій об’єкт списку, об’єктом, який я зберігаю в списку, є рядок “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" java.lang.ClassCastException: com.default.Animal не можна передати в java.lang.Comparable
ClassCastException
буде кинуто заповіт. Отже, якщо елементи не реалізуються,Comparable
тодіCollections.sort()
викине цей виняток