当前位置: 首页 > 知识库问答 >
问题:

Java原始类型值分配给泛型类型运行时getClss()方法错误

哈和惬
2023-03-14
public class Box<T> {
    private T t;
    public Box(T t){
        this.t = t;
    }
    public void add(T t) {
      this.t = t;
    }
    public T get() {
      return t;
    }
    public static void main(String[] args) {
      Box<Integer> b = new Box(new String("may be"));
      System.out.println(b.get()); // successfully print out "may be"
      System.out.println(b.get().getClass()); // error
   }
}

这段代码给出了一个运行时错误:

exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    < li >为什么< code>b.get()不会触发运行时错误? < li >为什么只有当我试图获取class变量的类时才会出现运行时错误?

更准确地说:为什么编译器仅为第二个get()(导致异常)在字节码中插入检查广播指令?

共有3个答案

司空海荣
2023-03-14

除了这里的答案之外,字节指令<code>checkcast

 public static void main(String[] args) {
          Box<Integer> b = new Box(new String("may be"));
          doStuff(b.get()); // no checkcast needed - works fine
          doIntegerStuff(b.get()); // run-time error with checkcast
          doStringStuff(b.get()); // compile error
       }

 public static void doStuff(Object object){}
 public static void doStringStuff(String integer){}
 public static void doIntegerStuff(Integer integer){}
江宏放
2023-03-14

此变量声明不一致。

  Box<Integer> b = new Box(new String("may be")); :

实例化的对象是原始的,因此编译器会发出有关它的警告,但允许将原始类型分配给泛型变量:Box

< code>b.get()不会失败,因为您没有将结果赋给变量。< br >因此编译器不需要将其转换为任何类型。< br >

试试那个:

Integer value = b.get();

它会很好地编译,但您将在运行时获得相同的异常,因为JVM将尝试将值强制转换为整数

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer

当您调用时:

System.out.println(b.get().getClass()); // error

事情都近在咫尺。

为什么这里需要< code>Integer类?< br >

在编译时,b 被声明为 Box

这里的情况就是这样。
在使用 Integer 参数化的变量上调用 getClass()。
是一个泛型类:

当然,通过对变量声明和实例化使用泛型:

  Box<Integer> b = new Box<>(new String("may be"));

这种不一致是不可能的,因为编译器现在就停止了您。

陶博涉
2023-03-14

请注意:

  • 在第一种情况下,get()的结果用于println(Object):换句话说,接收方需要一个Object,而“condition”将始终为true
  • 在第二种情况下,将对返回的对象进行方法调用。现在,如果返回的类型是预期的类型,它将产生巨大的影响。因此,编译器正在添加此检查以确保以下方法调用是正确的

作为背景,人们可以查看Java语言规范,第5.52章:

演员阵容是格纹演员阵容。

这种转换需要运行时有效性检查。如果运行时的值为空,则允许强制转换。否则,设R为运行时引用值所引用对象的类,T为强制转换运算符中指定类型的擦除(§4.6)。强制转换必须在运行时通过§5.5.3中的算法检查类别R是否与类型T的赋值兼容。

第5.53章在运行时检查强制转换。

 类似资料:
  • 我读了很多文章,但我不明白这两行之间的区别: 我看到的唯一区别是第一行触发了“未检查的分配”警告。

  • 在下面来自的语法中,泛型类型参数在实例化原始类型数组后用于类型转换,

  • 问题内容: 我目前正在尝试从书中学习如何使用泛型。在本章中,它说取一条数据T并将其转换为整数。我正在Eclipse中尝试不同的方法,但是似乎都不允许这样做。您如何执行以下任务: 然后在另一个类中: 我已经尝试使用和其他一些东西,但似乎没有什么能使Java满意。本书坚持要保持方法的通用性,以防使用浮点数或双精度数代替字符串或整数。 编辑:对于其他人可能有类似的问题。从对这个问题的所有评论和被接受的答

  • 问题内容: 如果在Java中创建泛型类(该类具有泛型类型参数),则可以使用泛型方法(该方法带有泛型类型参数)吗? 考虑以下示例: 正如您对通用方法所期望的那样,我可以使用任何对象调用的实例: 但是,如果我尝试使用 不 指定泛型类型的实例,则无论传入什么,我都会调用返回, 奇怪的是,如果返回类型是通用类,它将编译(例如(实际上,这可以解释-参见下面的答案)): 此外,如果输入通用类,即使仅使用通配符

  • 如果在Java中创建泛型类(该类具有泛型类型参数),是否可以使用泛型方法(该方法采用泛型类型参数)? 考虑下面的例子: 正如您所期望的那样,对于任何对象,的实例,我都可以调用: 但是,如果我试图使用的实例而不指定泛型类型,那么调用将返回一个

  • JavaScript 允许我们像使用对象一样使用原始类型(字符串,数字等)。JavaScript 还提供了这样的调用方法。我们很快就会学习它们,但是首先我们将了解它的工作原理,毕竟原始类型不是对象(在这里我们会分析地更加清楚)。 我们来看看原始类型和对象之间的关键区别。 一个原始值: 是原始类型中的一种值。 在 JavaScript 中有 7 种原始类型:string,number,bigint,