我阅读了一些关于“ClassCastException”的文章,但我无法很好地理解它的含义。什么是 ClassCastException?
12 回答
直接来自 API 规范ClassCastException
:
抛出以指示代码已尝试将对象强制转换为它不是实例的子类。
因此,例如,当尝试将 an 强制转换Integer
为 aString
时,String
它不是 的子类Integer
,因此 aClassCastException
将被抛出。
Object i = Integer.valueOf(42);
String s = (String)i; // ClassCastException thrown here.
这真的很简单:如果你试图将 A 类的对象类型转换为 B 类的对象,并且它们不兼容,你会得到一个类转换异常。
让我们考虑一个类的集合。
class A {...}
class B extends A {...}
class C extends A {...}
- 您可以将这些东西中的任何一个转换为 Object,因为所有 Java 类都继承自 Object。
- 您可以将 B 或 C 转换为 A,因为它们都是 A 的“种类”
- 只有当真实对象是B 时,才能将对 A 对象的引用强制转换为 B。
- 即使它们都是 A,您也不能将 B 转换为 C。
如果您尝试向下转换一个类,则会发生异常,但实际上该类不是该类型。
考虑这个层次结构:
对象 -> 动物 -> 狗
你可能有一个方法叫做:
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
:
- 尝试将一个类的对象转换为另一个类时要小心。确保新类型属于其父类之一。
- 您可以通过使用泛型来防止 ClassCastException,因为泛型提供编译时检查并可用于开发类型安全的应用程序。
你了解铸造的概念吗?强制转换是类型转换的过程,这在 Java 中很常见,因为它是一种静态类型的语言。一些例子:
将字符串"1"
转换为int
, via Integer.parseInt("1")
-> 没问题
将字符串"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 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.
当您尝试将一种数据类型的对象转换为另一种数据类型时,Java 会引发类转换异常。
只要转换发生在兼容的数据类型之间,Java 就允许我们将一种类型的变量转换为另一种类型。
例如,您可以将字符串转换为对象,类似地,可以将包含字符串值的对象转换为字符串。
例子
让我们假设我们有一个包含许多 ArrayList 对象的 HashMap。
如果我们这样写代码:
String obj = (String) hmp.get(key);
它会抛出一个类转换异常,因为哈希映射的 get 方法返回的值将是一个数组列表,但我们正试图将它转换为一个字符串。这将导致异常。
您试图将一个对象视为不是一个类的实例。这大致类似于试图按下吉他上的制音踏板(钢琴有制音踏板,吉他没有)。
一旦您意识到 JVM 无法猜测未知数,您就可以更好地理解 ClassCastException 和强制转换。如果 B 是 A 的实例,它在堆上的类成员和方法比 A 多。JVM 无法猜测如何将 A 强制转换为 B,因为映射目标更大,并且 JVM 将不知道如何填充额外的成员。
但是如果 A 是 B 的一个实例,这是可能的,因为 A 是对 B 的完整实例的引用,所以映射将是一对一的。
我可以给你的 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,所以会引发异常。
异常不是 RuntimeException -> ClassCastException 的子类
final Object exception = new Exception();
final Exception data = (RuntimeException)exception ;
System.out.println(data);
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 方法将在运行时类转换异常下面抛出
线程“主”java.lang.ClassCastException 中的异常:com.default.Animal 无法转换为 java.lang.Comparable