我读了一些关于“ClassCastException”的文章,但我无法对此有所了解。是否有一篇好文章或什么是简短的解释?
直接来自ClassCastException
的API规范:
抛出以指示代码已尝试将对象强制转换为不是实例的子类。
因此,例如,当一个人试图将Integer
施放到String
时,String
不是Integer
的子类,因此将抛出ClassCastException
。
Object i = Integer.valueOf(42);
String s = (String)i; // ClassCastException thrown here.
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。
如果你想对对象进行排序,但是如果类没有实现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
这非常简单:如果您试图将类A的对象类型转换为类B的对象,并且它们不兼容,则会出现类转换异常。
让我们想一下课程的集合。
class A {...}
class B extends A {...}
class C extends A {...}
如果您尝试向下转换类,则会发生异常,但实际上该类不属于该类。
考虑此层次结构:
对象 - >动物 - >狗
您可能有一个名为的方法:
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
}
考虑一个例子,
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
:
你了解铸造的概念吗?转换是类型转换的过程,它在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.
您正在尝试将对象视为类的实例而不是它。这大致类似于试图按下吉他上的制音踏板(钢琴有阻尼踏板,吉他没有)。
当您尝试将一种数据类型的Object转换为另一种数据类型时,Java会抛出类强制转换异常。
只要在兼容的数据类型之间进行转换,Java允许我们将一种类型的变量转换为另一种类型。
例如,您可以将String转换为Object,类似地,包含String值的Object可以转换为String。
让我们假设我们有一个包含许多ArrayList对象的HashMap。
如果我们编写这样的代码:
String obj = (String) hmp.get(key);
它会抛出一个类转换异常,因为哈希映射的get方法返回的值将是一个Array列表,但我们正试图将它转换为String。这会导致异常。
我可以在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,所以会抛出异常。
一旦您意识到JVM无法猜测未知,您就可以更好地理解ClassCastException并进行转换。如果B是A的实例,则堆上的类成员和方法比A多.JVM无法猜测如何将A转换为B,因为映射目标较大,并且JVM将不知道如何填充其他成员。
但是如果A是B的实例,那么它是可能的,因为A是对B的完整实例的引用,因此映射将是一对一的。