Объяснение «ClassCastException» в Java - PullRequest
68 голосов
/ 25 мая 2009

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

Ответы [ 11 ]

104 голосов
/ 25 мая 2009

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

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

Так, например, когда кто-то пытается привести Integer к String, String не является подклассом Integer, поэтому будет выброшено ClassCastException.

Object i = Integer.valueOf(42);
String s = (String)i;            // ClassCastException thrown here.
75 голосов
/ 25 мая 2009

Это действительно довольно просто: если вы пытаетесь типизировать объект класса 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, даже если они оба А.
19 голосов
/ 25 мая 2009

Это исключение, которое возникает, если вы пытаетесь понизить класс, но на самом деле этот класс не относится к этому типу.

Рассмотрим эту иерархию:

Объект -> Животное -> Собака

Возможно, у вас есть метод с именем:

 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
 }
9 голосов
/ 05 апреля 2013

Рассмотрим пример,

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 предоставляют проверки времени компиляции и могут использоваться для разработки безопасных типов приложений.

Источник Записки и Остального

5 голосов
/ 25 мая 2009

Ты понимаешь концепцию кастинга? Кастинг - это процесс преобразования типов, который в 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.
4 голосов
/ 25 мая 2009

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

3 голосов
/ 05 октября 2012

Исключение приведения класса выдается Java при попытке приведения объекта одного типа данных к другому.

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

Например, вы можете привести String как объект, а также объект, содержащий значения String, можно привести к String.

Пример

Предположим, у нас есть HashMap, который содержит несколько объектов ArrayList.

Если мы напишем код, подобный этому:

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

это вызовет исключение приведения класса, потому что значение, возвращаемое методом get хэш-карты, будет списком массивов, но мы пытаемся привести его к строке. Это вызвало бы исключение.

2 голосов
/ 16 ноября 2013

Очень хороший пример, который я могу привести для исключения classcastException в Java, при использовании "Collection"

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

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

Этот код выше даст вам ClassCastException во время выполнения. Поскольку вы пытаетесь привести Integer к String, это вызовет исключение.

2 голосов
/ 02 апреля 2013

Вы можете лучше понять ClassCastException и приведение типов, когда поймете, что JVM не может угадать неизвестное. Если B является экземпляром A, у него в куче больше членов класса и методов, чем A. JVM не может угадать, как привести A к B, поскольку цель сопоставления больше, и JVM не будет знать, как заполнить дополнительные члены.

Но если бы A был экземпляром B, это было бы возможно, потому что A - это ссылка на полный экземпляр B, поэтому отображение будет однозначным.

0 голосов
/ 18 сентября 2018

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

...