java list 泛型 继承 强制转换,java泛型与强制类型转换解决方法

java泛型与强制类型转换

首先如果Object[]强转为String[],运行时是要报错的,如下,但编译能够成功

Object[] o = {"2","sd"};

String[] s = (String[])o;//编译成功,但运行时报错

然后因为能编译成功,我们看看反编译的结果

6: ldc           #3                  // String 2

8: aastore

9: dup

10: iconst_1

11: ldc           #4                  // String sd

13: aastore

14: astore_1

15: aload_1

16: checkcast     #5                  // class "[Ljava/lang/String;"

19: checkcast     #5                  // class "[Ljava/lang/String;"

上面两个checkcast,表明运行时会进行(String[])o:Object[]转String[]的类型判断,以及String[] s = (String[])o:String[]转String[]的类型判断,最后运行时类型转换报错Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;at ConvertTest.main(ConvertTest.java:7)

但是到了泛型里面似乎又可以转换了,这里让人百思不得其解,跪求大神指点。情况如下:

public static void main(String[] args) {

// Object[] o = {"2","sd"};

// String[] s = (String[])o;

String[] i = {"1","2"};

String[] s1 = getElement(i);//成功运行

getElement(i).getClass();//返回String[]类型

}

public static  T[] getElement(T[] obj){

return obj;

}

我写了一个泛型方法,由于泛型擦除,最后getElement()方法返回的肯定是Object[](接下来贴反编译文件,也能证明),然后却成功的转换成了String[]类型,这里好奇怪,不理解。

24: invokestatic  #5                  // Method getElement:([Ljava/lang/Object;)[Ljava/lang/Object;

//这里调用getElement方法,返回类型为Ljava/lang/Object即Object[]

27: checkcast     #6                  // class "[Ljava/lang/String;"

/这里也会在运行进行类型转换判断,但结果是运行过去了

30: invokevirtual #7                  // Method java/lang/Object.getClass:()Ljava/lang/Class;

public static  T[] getElement(T[]);

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=1, locals=1, args_size=1

0: aload_0

1: areturn

LineNumberTable:

line 13: 0

Signature: #20                          // ([TT;)[TT;

真的不理解,同样有checkcast,一个运行时出错,一个运行通过,我到底哪里想错了,求高人指点

------解决思路----------------------

因为 Java 在编译的时候,根本就不会在意你的具体类型,只要你进行一次强制类型转换, Java 就默认你已经知道他的正确类型了

比如说,有一个类 A, 继承了 B,C 两种接口,然后我们令 B b = new A();那么如果希望使用到 b 的 C 接口的方法,我们就得进行类型转换  C c = (C) b;但是 B,C 之间又没有明确的继承关系,所以Java 为了避免这种情况,就允许强制类型转换不正确的类型.

只有当你具体运行到代码的时候,才会根据实际类型抛出异常

------解决思路----------------------

引用:Quote: 引用:因为 Java 在编译的时候,根本就不会在意你的具体类型,只要你进行一次强制类型转换, Java 就默认你已经知道他的正确类型了

比如说,有一个类 A, 继承了 B,C 两种接口,然后我们令 B b = new A();那么如果希望使用到 b 的 C 接口的方法,我们就得进行类型转换  C c = (C) b;但是 B,C 之间又没有明确的继承关系,所以Java 为了避免这种情况,就允许强制类型转换不正确的类型.

只有当你具体运行到代码的时候,才会根据实际类型抛出异常虽然说楼主的回答并没能解答我上面问题的疑惑,但楼主提到的这种运行处类型转换错误的原因真心受教了,的确这是个值得注意的点。

你确定范型擦除了数据了吗?擦除数据是当数组形式为 LIst[]时才会将类型擦除,你直接使用 String[]类型是保留的,怎么会擦除类型呢

------解决思路----------------------

你的类型转换不是通过擦除得到的,范型都会有类似的类型转换,但是擦除和这种类型转换是不一样的,

当你使用范型的时候, java 会记录你的数据类型,当操作完成,再强制转换为之前应该有得类型,但这个不叫做擦除

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值