Объяснение "ClassCastException" в Java


Я читал некоторые статьи, написанные на "ClassCastException", но я не мог получить хорошее представление об этом. Есть ли хорошая статья или что было бы краткое объяснение?

11 57

11 ответов:

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

брошенный, чтобы указать, что код попытка привести объект к a подкласс которого он не является пример.

так, например, когда кто-то пытается бросить Integer до 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 {...}
  1. вы можете привести любую из этих вещей к объекту, потому что все классы Java наследуются от объекта.
  2. вы можете привести либо B, либо C К A, потому что они оба "виды" A
  3. вы можете привести ссылку на объект A к Б только если реальный объект-это B.
  4. вы не можете бросить 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:

  1. будьте осторожны при попытке привести объект класса в другой класс. Убедитесь, что новый тип принадлежит к одному из родительских классов.
  2. вы можете предотвратить 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.ленг.Сравним