关于泛型的一个比较有意思的内容,List<String>转List<Integer>的一个问题

之前刷B站遇到一个很有意思的问题,就是一个list里面被塞入了String类型的数值,我的第一个想法是触发了一个类型强制转换所以才能赋值成功,没想到不是这样这和java泛型机制有关,java的泛型其实是假泛型类型T在运行的时候已经被擦除,如果通过反射注入值不判断类型是存在一些类型不安全的隐患的。

问题的一个简单说明

在这里插入图片描述
在这里插入图片描述
这个问题是不是很神奇,list<integer>里面居然输出了字符串。在值赋值的时候无感,但是在取值使用的时候就会报错了。但是这个取第0个值的时候也没有报错,这也是我现在也比较迷惑的地方。
下面这个链接就是视频出处。
【一个非常隐蔽的BUG!泛型的正确使用方式!高级面试高频题!-哔哩哔哩】 https://b23.tv/GppCwWz

问题复现

这个copy的赋值逻辑大概猜想了一下。

public class 集合泛型强转 {
    List<Integer> i1;
    List<String> s1;
    @Before
    public void b1(){
        i1=new ArrayList<>();;
        s1=new ArrayList<>();
        s1.addAll(Arrays.asList("s1","s2","s3"));
    }

    @Test
    public void t1() throws NoSuchFieldException, IllegalAccessException {
        //获得一个list的class对象
        Class<? extends List> listClass = s1.getClass();
        //获得需要的两个反射字段,目前就我的了解来说需要这两个字段 elementData存放元素、size存放含有多少元素
        //目前来说arraylist应该可以用 其他的list子类具体分析
        Field elementData = listClass.getDeclaredField("elementData");
        Field size = listClass.getDeclaredField("size");
        //设置字段可访问
        size.setAccessible(true);
        elementData.setAccessible(true);
        //获取s1的elementData元素值
        Object o = elementData.get(s1);
        //设置i1的元素值和长度
        elementData.set(i1,o);
        size.set(i1,s1.size());
        System.out.println(i1.get(0));
    }
}

i1里面就存在了一些非Integer的数值类型了
在这里插入图片描述
如果我想获取这个参数的泛型怎么解决呢?我暂时想不到,下面的就是通过类的对象属性来获取泛型类型

    @Test
    public void t2(){
        Class<集合泛型强转> c1 = 集合泛型强转.class;
        Field[] declaredFields = c1.getDeclaredFields();
        for (Field f:declaredFields){
            Type genericType = f.getGenericType();
            //如果类型带有泛型参数
            if (genericType instanceof ParameterizedType) {
                //ParameterizedType进行类型参数转换
                genericType=(ParameterizedType)genericType;
                Type[] actualTypeArguments = ((ParameterizedType) genericType).getActualTypeArguments();
                //因为泛型参数只有一个就直接取0了
                Type actualTypeArgument = actualTypeArguments[0];
                System.out.println(actualTypeArgument);
            }
        }
    }

结果是正确的
在这里插入图片描述

一个问题

如果这个参数不在类里面,而只是一个普普通的形式参数,我该怎么判断他们的泛型是否一致呢?

我想到的:1、还是通过泛型类型来限制他们必须是同一类型的值
2、就是一个很简单的判断,当然要判断非空,既然是赋值操作如果源对象为空接下来的步骤都不用走了

@Test
    public  void t3(){
        System.out.println(s1.get(0).getClass());
    }

有其他想法的可以下面留言,一起交流进步。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值