Java中“ClassCastException”的解释

我读了一些写在“ClassCastException”上的文章,但是我不明白这一点。 有没有好的文章,或者是一个简短的解释?

直接从ClassCastException的API规范:

抛出以表明代码已经尝试将对象转换为其不是实例的子类。

因此,例如,当试图将一个Integer为一个StringString不是Integer一个子类,所以ClassCastException一个ClassCastExceptionexception。

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

这真的很简单:如果您试图将类A的对象types转换为类B的对象,并且它们不兼容,则会得到类转换exception。

让我们来思考一个类的集合。

 class A {...} class B extends A {...} class C extends A {...} 
  1. 您可以将这些东西中的任何一个转换为Object,因为所有Java类都从Objectinheritance。
  2. 你可以投B或C到A,因为他们都是“种”A
  3. 只有当真实物体是B时, 可以将A物体的引用转换为B.
  4. 即使他们都是A,你也不能投B。

这是一个exception,如果你试图向下转换一个类,但实际上该类不是这种types的。

考虑这个问题:

对象 – >动物 – >狗

你可能有一个方法叫做:

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

如果用这个代码调用:

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

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

在更高版本的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因为你不能使用Goat创buildAnother类的实例。

注意 :只有在类扩展父类并将子类转换为其父类时,转换才有效。

如何处理ClassCastException

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

注意和其他的来源

你明白铸造的概念吗? 铸造是types转换的过程,这在Java中是非常常见的,因为它是一种静态types的语言。 一些例子:

将string“1”投射到一个int – >没有问题

将string“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 cant cast a dog to a cat 

你正试图把一个对象当作一个不是的类的实例。 这大致类似于尝试按吉他上的延音踏板(钢琴有阻尼踏板,吉他没有)。

当您尝试将一个数据types的Object转换为另一个数据types的对象时,Java抛出类抛出exception。

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

例如,您可以将一个string作为对象进行强制转换,同样可以将一个包含string值的对象转换为一个string。

让我们假设我们有一个包含多个ArrayList对象的HashMap。

如果我们写这样的代码:

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

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

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

 List list = new ArrayList(); list.add("Java"); list.add(new Integer(5)); for(Object obj:list) { String str = (String)obj; } 

上面的代码会在运行时给你ClassCastException。 因为你正试图将整数转换为string,这将抛出exception。

一旦您意识到JVM无法猜测未知,您可以更好地理解ClassCastException并进行投射。 如果B是A的一个实例,那么堆中的类成员和方法比A多。JVM不能猜测如何将A转换为B,因为映射目标较大,JVM不知道如何填充其他成员。

但是,如果A是B的一个实例,那么这将是可能的,因为A是对B的完整实例的引用,所以映射将是一对一的。

下面的伪代码将以更好的方式解释它。

 if (object to be casted follows an "ISA" relationship with the classtype it is being casted to) { There will not be any exception } else { It will throw class cast exception. }