Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中ClassCastException的解释_Java_Casting_Classcastexception - Fatal编程技术网

Java中ClassCastException的解释

Java中ClassCastException的解释,java,casting,classcastexception,Java,Casting,Classcastexception,我读了一些关于“ClassCastException”的文章,但我对它的含义没有一个好的理解。什么是ClassCastException?直接来自以下API规范: 抛出以指示代码已 试图将对象强制转换为 它不是的子类 例如 因此,例如,当尝试将整数强制转换为字符串时,字符串不是整数的子类,因此将抛出ClassCastException Object i = Integer.valueOf(42); String s = (String)i; // ClassCastExce

我读了一些关于“ClassCastException”的文章,但我对它的含义没有一个好的理解。什么是ClassCastException?

直接来自以下API规范:

抛出以指示代码已 试图将对象强制转换为 它不是的子类 例如

因此,例如,当尝试将
整数
强制转换为
字符串
时,
字符串
不是
整数
的子类,因此将抛出
ClassCastException

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

这真的很简单:如果您试图将类A的对象类型转换为类B的对象,但它们不兼容,则会出现类转换异常

让我们考虑一组类

class A {...}
class B extends A {...}
class C extends A {...}
  • 您可以将这些内容中的任何一个强制转换为对象,因为所有Java类都继承自对象
  • 你可以将B或C转换为A,因为它们都是A的“种类”
  • 只有当真实对象是B时,才能将对a对象的引用强制转换为B
  • 即使他们都是a,你也不能把B换成C

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

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

    将字符串“abc”强制转换为int->引发ClassCastException

        final Object  exception = new Exception();
        final Exception data = (RuntimeException)exception ;
        System.out.println(data);
    
    或者想象一个包含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.
    

    您试图将一个对象视为它不是的类的实例。这大致类似于试图踩下吉他上的减震踏板(钢琴有减震踏板,吉他没有)。

    如果你试图贬低一个类,这是一个例外,但事实上该类不是那种类型

    以这一继承权为例:

    对象->动物->狗

    您可能有一个名为:

     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
     }
    

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

    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允许我们将一种类型的变量转换为另一种类型,只要转换发生在兼容的数据类型之间

    例如,可以将字符串转换为对象,类似地,可以将包含字符串值的对象转换为字符串

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

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

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

    它将抛出类强制转换异常,因为哈希映射的get方法返回的值将是数组列表,但我们正试图将其强制转换为字符串。这将导致异常。

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

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

    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();
        }
    }
    
    other t5=(other)new Goat()
    :您将得到一个
    ClassCastException
    ,因为您无法使用
    Goat
    创建另一个
    类的实例

    注意:转换仅在类扩展父类且子类强制转换为其父类的情况下有效

    如何处理
    ClassCastException

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

  • 我可以为您提供一个关于Java中classcastException的非常好的例子,就是在使用“Collection”时


    上述代码将在运行时为您提供ClassCastException。因为您试图将Integer转换为字符串,这将引发异常。

    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)
    

    这里抛出异常的原因是,当我创建列表对象时,我存储在列表中的对象是字符串“1”,但后来当我试图取出此对象时,我故意犯了一个错误,试图将其转换为整数。因为字符串不能直接转换为整数-整数不是字符串的类型-所以会抛出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.com


    Exception不是RuntimeException->ClassCastException的子类

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

    有点吹毛求疵,但字符串“1”不能“转换”为int,但可以通过Integer.parseInt(String)方法将其转换为int。将字符串“1”转换为int->没问题?这是错误的,即使是
    catc=(Dog)a
    也不会引发
    ClassCastException
    ,但编译器错误(类型不匹配)不一定是向下转换的-如果Cat是动物的子类,并且您尝试向Dog进行转换,您将得到相同的例外情况,任何类型的排序,所有项都必须彼此可比(相互可比)。如果不是,则会出现
    ClassCastException