Пояснення “ClassCastException” на Java


Відповіді:


118

Прямо зі специфікацій API для ClassCastException:

Кидається, щоб вказати, що код намагався передати об'єкт підкласу, екземпляром якого він не є.

Так, наприклад, коли хтось намагається кинути Integera String, Stringне є підкласом Integer, тому a ClassCastExceptionбуде кинуто.

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

2
При будь-якому сортуванні всі предмети повинні бути порівнянними між собою (взаємопорівняно). Якщо їх немає, ClassCastExceptionбуде кинуто заповіт. Отже, якщо елементи не реалізуються, Comparableтоді Collections.sort()викине цей виняток
переобмін

92

Це насправді досить просто: якщо ви намагаєтесь ввести об’єкт класу A в об’єкт класу B, але вони не сумісні, ви отримаєте виняток класу класу.

Давайте подумаємо про колекцію занять.

class A {...}
class B extends A {...}
class C extends A {...}
  1. Ви можете передати будь-яку з цих речей в Object, оскільки всі класи Java успадковуються від Object.
  2. Ви можете перекласти B або C на A, тому що вони обидва "різновиди" A
  3. Ви можете передати посилання на об'єкт A на B, лише якщо реальним об'єктом є B.
  4. Ви не можете передати B на C, хоча вони обидва A.

21

Це виняток, який виникає, якщо ви намагаєтесь знизити клас, але насправді клас не такого типу.

Розглянемо цю ієрархію:

Об'єкт -> Тварина -> Собака

У вас може бути метод, який називається:

 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
 }

2
Не обов’язково пригнічений - якщо Кіт був підкласом Тварини, і ви намагалися кинути собаку, ви отримали б такий самий виняток
барі

13

Розглянемо приклад,

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:

  1. Будьте обережні, намагаючись перекинути об’єкт класу в інший клас. Переконайтеся, що новий тип належить до одного з батьківських класів.
  2. Ви можете запобігти ClassCastException, використовуючи Generics, оскільки Generics забезпечує перевірку часу компіляції і може використовуватися для розробки безпечних для типу програм.

Джерело примітки та решти


4

Ви намагаєтеся розглядати об'єкт як екземпляр класу, яким він не є. Це приблизно аналогічно спробі натиснути на гітару на педалі заслінки (піаніно має педалі заслінки, гітари - ні).


4

Ви розумієте концепцію кастингу? Кастинг - це процес перетворення типів, який у 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.

14
Будучи трохи нікчемним, але рядок "1" не може бути "перекинутий" на int, але його можна перетворити на int за допомогою методу Integer.parseInt (String).
coobird

2
Передати рядок "1" до int -> немає проблем? це неправильно
karlihnos

1
Навіть Cat c = (Dog) aне спричинить ClassCastExceptionпомилку, але помилка компілятора ( невідповідність типу )
Тобіас Лієфке,

3

Виняток класу для класу передається Java, коли ви намагаєтесь передати об’єкт одного типу даних іншому.

Java дозволяє передавати змінні одного типу іншому, доки відбувається перекидання між сумісними типами даних.

Наприклад, ви можете передати рядок як об'єкт, а також об'єкт, що містить значення рядка, можна передати в рядок.

Приклад

Припустимо, у нас є HashMap, що містить ряд об’єктів ArrayList.

Якщо ми пишемо код так:

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

це викине виняток класу для класу, оскільки значення, яке повертається методом get на карті хешу, буде списком масиву, але ми намагаємося передати його в рядок. Це спричинило б виняток.


2

Дуже хороший приклад, який я можу надати вам для classcastException на Java, - це використання "Колекції"

List list = new ArrayList();
list.add("Java");
list.add(new Integer(5));

for(Object obj:list) {
    String str = (String)obj;
}

Цей наведений вище код надасть вам ClassCastException під час виконання. Оскільки ви намагаєтесь привести ціле число до рядка, це викличе виняток.


2

Ви можете краще зрозуміти ClassCastException та кастинг, коли зрозумієте, що JVM не може вгадати невідоме. Якщо B є екземпляром A, то в купі більше членів класу та методів, ніж A. JVM не може здогадатися, як передати A до B, оскільки ціль відображення більша, і JVM не знатиме, як заповнити додаткові члени.

Але якби A був екземпляром B, це було б можливо, оскільки A є посиланням на повний екземпляр B, тому відображення буде один на один.


0

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.


0

Якщо ви хочете сортувати об'єкти, але якщо клас не реалізував 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


0

Виняток не є підкласом RuntimeException -> ClassCastException

    final Object  exception = new Exception();
    final Exception data = (RuntimeException)exception ;
    System.out.println(data);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.