加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 为什么隐式转换在反射投射抛出异常时有效?

发布时间:2020-12-14 19:37:12 所属栏目:Java 来源:网络整理
导读:假设有以下代码: @SuppressWarnings("unchecked")public static T T implicitCaster(ClassT cls,Object o) { return (T) o;}public static T T reflectionCaster(ClassT cls,Object o) { return cls.cast(o);} 代码在两种情况下都按预期工作,但在基元中有以
假设有以下代码:
@SuppressWarnings("unchecked")
public static  <T> T implicitCaster(Class<T> cls,Object o) {
    return (T) o;
}

public static <T> T reflectionCaster(Class<T> cls,Object o) {
    return cls.cast(o);
}

代码在两种情况下都按预期工作,但在基元中有以下异常:

public static void main(String[] args) {
    System.out.println(implicitCaster(int.class,42));
    System.out.println(reflectionCaster(int.class,42));
}

第一个调用按预期工作,但第二个调用抛出java.lang.ClassCastException.

这是一个不考虑自动装箱的角落案例吗?或者在这种情况下,反射铸造是否不可能提供自动装箱?
或者是否有其他原因导致这种不一致?

编辑:调用此代码按预期工作:

public static void main(String[] args) {
    System.out.println(implicitCaster(Integer.class,42));
    System.out.println(reflectionCaster(Integer.class,42));
}

解决方法

这是因为类型擦除.

在运行时,不存在泛型类型参数.
将对象转换为泛型类型参数无效. (这就是为什么你得到未经检查的演员警告)

因此,您的第一行自动装箱42将Object传递给该方法.
然后该函数返回该Object,该Object将传递给System.out.println.

您的第二个调用调用int基本类型的强制转换方法.
这会引发异常,因为对象无法转换为基本类型. (自动装箱是一个纯粹的编译时功能,所以它没有帮助)

当cast()checks isInstance()验证转换有效时,会发生错误.

isInstance() say的文档:

Specifically,if this Class object represents a declared class,this method returns true if the specified Object argument is an instance of the represented class (or of any of its subclasses); it returns false otherwise. If this Class object represents an array class,this method returns true if the specified Object argument can be converted to an object of the array class by an identity conversion or by a widening reference conversion; it returns false otherwise. If this Class object represents an interface,this method returns true if the class or any superclass of the specified Object argument implements this interface; it returns false otherwise. If this Class object represents a primitive type,this method returns false.

(重点补充)

您的编辑有效,因为您不再使用基本类型.
在这两种情况下,编译器都会自动装箱42,以便它可以作为对象传递.

与以前一样,第一次通话无效.第二个调用验证盒装整数实际上是Integer类的实例,然后返回它.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读