Java中“ ClassCastException”的说明


Answers:


117

直接来自API规范ClassCastException

抛出该异常以指示代码已尝试将对象强制转换为不是实例的子类。

因此,例如,当一个人尝试将an强制转换Integer为a时StringString它不是的子类Integer,因此ClassCastException会抛出a。

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

2
进行任何排序时,所有项目都必须彼此可比较(相互可比较)。如果不是,ClassCastException将抛出a。所以,如果项目没有实现Comparable然后Collections.sort()将抛出此异常
overexchange

92

这真的很简单:如果您试图将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. 即使它们都是A,也不能将B转换为C。

1
沙发上最好的例子。
亚当·瓦赫吉

21

如果您尝试向下转换一个类,则会发生此异常,但实际上该类不是该类型的。

考虑以下层次结构:

对象->动物->狗

您可能有一个称为的方法:

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

如果使用以下代码调用:

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

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

在更高版本的Java中,除非您执行以下操作,否则会收到编译器警告:

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

2
不一定沮丧-如果猫是动物的半影半物,而您试图投射到狗,则会遇到相同的例外情况
-Barry

12

考虑一个例子,

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,因为泛型提供了编译时检查,并可用于开发类型安全的应用程序。

注释和其余部分的来源


4

您试图将对象视为不是的类的实例。大致类似于尝试踩吉他的阻尼器踏板(钢琴带有阻尼器踏板,而吉他没有阻尼器)。


4

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

将字符串“ 1”强制转换为整数->没问题

将字符串“ abc”转换为整数->引发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,但可以通过Integer.parseInt(String)方法将其转换为int。
coobird

2
将字符串“ 1”强制转换为int->没问题吗?多数民众赞成在错
karlihnos

甚至Cat c = (Dog) a不会引发ClassCastException,而是编译器错误(类型不匹配
Tobias Liefke

3

当您尝试将一种数据类型的对象转换为另一种数据类型时,Java会引发类转换异常。

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

例如,您可以将字符串强制转换为对象,并且类似地,可以将包含字符串值的对象强制转换为字符串。

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

如果我们这样写代码:

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

它将引发类强制转换异常,因为哈希映射表的get方法返回的值将是Array列表,但是我们试图将其强制转换为String。这将导致异常。


2

我可以为您提供Java中的classcastException的一个很好的例子是在使用“集合”时

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

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

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


2

一旦意识到JVM无法猜测未知内容,就可以更好地理解ClassCastException和强制转换。如果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”,但是后来当我尝试取出该对象时,我有意通过尝试犯错将其转换为整数。因为不能将String直接转换为Integer(Integer不是String的类型),所以将引发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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.