Java 中 ClassCastException 的解释

Explanation of ClassCastException in Java

提问人:Chathuranga Chandrasekara 提问时间:5/26/2009 最后编辑:Zoe is on strikeChathuranga Chandrasekara 更新时间:8/13/2021 访问量:345947

问:

我读了一些关于“ClassCastException”的文章,但我无法很好地理解它的含义。什么是 ClassCastException?

Java 强制转换 类CastException

评论


答:

136赞 coobird 5/26/2009 #1

直接来自 ClassCastException 的 API 规范:

抛出以指示代码具有 试图将对象投射到 它不是子类 实例。

因此,例如,当人们试图将 an 转换为 时,它不是 的子类,因此将抛出 a。IntegerStringStringIntegerClassCastException

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

评论

2赞 overexchange 10/5/2017
对于任何类型的排序,所有项目都必须相互可比(相互可比)。如果不是,则将抛出一个。因此,如果项目未实现,则将引发此异常ClassCastExceptionComparableCollections.sort()
109赞 Charlie Martin 5/26/2009 #2

这真的很简单:如果你试图将 A 类的对象类型转换为 B 类的对象,并且它们不兼容,你会得到一个类转换异常。

让我们考虑一个类的集合。

class A {...}
class B extends A {...}
class C extends A {...}
  1. 您可以将其中任何一个强制转换为 Object,因为所有 Java 类都继承自 Object。
  2. 您可以将 B 或 C 转换为 A,因为它们都是 A 的“种类”
  3. 仅当实际对象为 B 时,才能将对 A 对象的引用转换为 B。
  4. 你不能将 B 转换为 C,即使它们都是 A。
6赞 Mork0075 5/26/2009 #3

你了解铸造的概念吗?强制转换是类型转换的过程,这在 Java 中很常见,因为它是一种静态类型语言。一些例子:

通过 -> 将字符串转换为 ,没问题"1"intInteger.parseInt("1")

将 String 转换为 -> 引发"abc"intClassCastException

或者考虑一个带有 和 的类图Animal.classDog.classCat.class

Animal a = new Dog();
Dog d = (Dog) a; // No problem, the type animal can be casted to a dog, because it's a dog.
Cat c = (Dog) a; // Will cause a compiler error for type mismatch; you can't cast a dog to a cat.

评论

16赞 coobird 5/26/2009
有点吹毛求疵,但字符串“1”不能“强制转换”为 int,但可以通过 Integer.parseInt(String) 方法转换为 int。
2赞 karlihnos 8/31/2018
将字符串“1”转换为 int ->没问题吗?这是不对的
1赞 Tobias Liefke 1/16/2020
甚至不会引发 ,而是编译器错误(类型不匹配Cat c = (Dog) aClassCastException)
3赞 Jeremy Huiskamp 5/26/2009 #4

您正在尝试将对象视为类的实例,但它不是。这大致类似于尝试按下吉他上的阻尼器踏板(钢琴有阻尼器踏板,吉他没有)。

24赞 Yishai 5/26/2009 #5

这是一个异常,如果你试图向下转换一个类,但实际上该类不是该类型。

考虑一下这个层次结构:

对象 -> 动物 -> 狗

您可能有一个名为:

 public void manipulate(Object o) {
     Dog d = (Dog) o;
 }

如果使用此代码调用:

 Animal a = new Animal();
 manipulate(a);

它会编译得很好,但在运行时你会得到一个,因为 o 实际上是一个动物,而不是一只狗。ClassCastException

在更高版本的 Java 中,除非您这样做,否则您确实会收到编译器警告:

 Dog d;
 if(o instanceof Dog) {
     d = (Dog) o;
 } else {
     //what you need to do if not
 }

评论

3赞 barry 2/7/2017
不一定是沮丧的 - 如果 Cat 是 Animal 的副手,而你试图向 Dog 施法,你会得到同样的例外
4赞 shakun tyagi 10/5/2012 #6

当您尝试将一种数据类型的 Object 转换为另一种数据类型时,Java 会抛出类强制转换异常。

Java 允许我们将一种类型的变量转换为另一种类型的变量,只要转换发生在兼容的数据类型之间。

例如,可以将 String 强制转换为 Object,同样,可以将包含 String 值的 Object 强制转换为 String。

假设我们有一个 HashMap,它包含许多 ArrayList 对象。

如果我们像这样编写代码:

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

它会抛出类转换异常,因为哈希映射的 get 方法返回的值将是一个 Array 列表,但我们正在尝试将其转换为 String。这将导致异常。

2赞 Mistriel 4/2/2013 #7

一旦意识到 JVM 无法猜测未知,就可以更好地理解 ClassCastException 和强制转换。如果 B 是 A 的实例,则它在堆上的类成员和方法比 A 多。JVM 无法猜测如何将 A 转换为 B,因为映射目标较大,并且 JVM 不知道如何填充其他成员。

但是,如果 A 是 B 的实例,则有可能,因为 A 是对 B 的完整实例的引用,因此映射将是一对一的。

12赞 Elizabeth Courpalis 4/6/2013 #8

举个例子,

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()ClassCastExceptionAnotherGoat

: 仅当类扩展父类并将子类强制转换为其父类时,转换才有效。

如何处理:ClassCastException

  1. 尝试将一个类的对象转换为另一个类时要小心。确保新类型属于其父类之一。
  2. 可以使用泛型来防止 ClassCastException,因为泛型提供编译时检查,可用于开发类型安全的应用程序。

注释的来源及其他内容

2赞 Suganthan Madhavan Pillai 11/17/2013 #9

对于Java中的classcastException,我可以给你一个很好的例子是使用“Collection”

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

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

上面的代码将在运行时为您提供 ClassCastException。因为您尝试将 Integer 转换为 String,所以会引发异常。

0赞 Ananta Chandra Das 12/18/2017 #10

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”,但后来当我尝试将此对象取出时,我故意将其转换为整数。由于 String 不能直接转换为 Integer(Integer 不是 String 的类型),因此会引发 ClassCastException。

0赞 karepu 9/18/2018 #11

如果你想对对象进行排序,但如果类没有实现 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 方法会抛出下面的运行时类强制转换异常

线程“main”java.lang.ClassCastException 中的异常:com.default.Animal 无法转换为 java.lang.Comparable

1赞 Mami Alexandre 7/5/2020 #12

Exception 不是 RuntimeException -> ClassCastException 的子类

    final Object  exception = new Exception();
    final Exception data = (RuntimeException)exception ;
    System.out.println(data);