Вопрос

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

Это было полезно?

Решение

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

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

Так, например, когда кто-то пытается разыграть Integer к String, String не является подклассом Integer, так что 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. Вы можете привести любую из этих вещей к Object, поскольку все классы Java наследуются от Object.
  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();
    }
}

В Another t5 = (Another) new Goat():ты получишь ClassCastException потому что вы не можете создать экземпляр Another класс, использующий Goat.

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

Как бороться с ClassCastException:

  1. Будьте осторожны при попытке привести объект одного класса к другому классу.Убедитесь, что новый тип принадлежит одному из его родительских классов.
  2. Вы можете предотвратить ClassCastException, используя Generics, поскольку Generics обеспечивает проверку времени компиляции и может использоваться для разработки типобезопасных приложений.

Источник заметки и остального

Вы пытаетесь рассматривать объект как экземпляр класса, которым он не является.Это примерно аналогично попытке нажать демпферную педаль на гитаре (у пианино демпферные педали есть, а у гитары нет).

Вы понимаете концепцию кастинга?Приведение — это процесс преобразования типов, который очень распространен в 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.

Исключение приведения класса генерируется 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 во время выполнения.Поскольку вы пытаетесь привести Integer к String, это вызовет исключение.

Вы сможете лучше понять 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.

Если вы хотите сортировать объекты, но если класс не реализовал сопоставимый или компаратор, то вы получите, например, 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);
   }
}

Выше основного метода будет выброшено исключение приведения класса ниже времени выполнения.

Исключение в потоке «основной» java.lang.ClassCastException:com.default.Animal не может быть приведен к java.lang.Comparable

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top