Android中使用泛型,如下

Android中使用泛型,如下,第1张

有两个建议:

其一:写一个静态类,

Utiles.getObjFromJson() 在内部解析不同的类,返回的时候,返回一个Object就行。

其二:抽象成接口,

因为你有 items.add(new Notice(array.getJSONObject(i)))  估计有一些实体类都是需要解析的,那么 可以 抽象出来一个解析json的接口,items变成 ArrayList<JSONInterface> 这样的。

实现类继承抽象类并实现了所有抽象方法

但是,编译报错!!

报的是TopicListAdapter 类中没有实现onBindViewHolder方法,上面在抽象类中有一个泛型,这个泛型正好是抽象方法onBindViewHolder的第一个参数。这里TopicListAdapter 在继承时会继承BaseListAdapter中的内部类ViewHolder,也就是在TopicListAdapter 中也会有ViewHolder这个内部类,所以如果不指定是BaseListAdapter类中的ViewHolder则方法其实是这样定义的:

public void onBindViewHolder(TopicListAdapter.ViewHolder holder, int position) {}

很显然这不是抽象类中定义的方法(参数不一致),所以就造成无法覆盖!

ide没有没提示该错误!

Java的泛型是JDK5新引入的特性,为了向下兼容,虚拟机其实是不支持泛型,所以Java实现的是一种

伪泛型机制,也就是说Java在编译期擦除了所有的泛型信息,这样Java就不需要产生新的类型到字节码,

所有的泛型类型最终都是一种原始类型,在Java运行时根本就不存在泛型信息。

使用ASM ByteCode Viewer查看他的字节码

可以看到我们设置的泛型R,被擦除为Object了,这就是泛型擦除

他的bytecode为

可以看到我们限定了泛型的类型,那么他的bytecode是什么样的?

可以看到虽然我们在Plate2中只定义了一个set get方法,但是bytecode中却有两个,其中一个get set方法添加了synthetic bridge 表示这是一个桥接方法,作用是为了保持多态性,可以看到 CHECKCAST java/lang/Comparable ,检查类型是否为Comparable,如果是的话再去调用上边的 public set(Ljava/lang/Comparable)V 方法。可以这样理解, set(Ljava/lang/Object)V 是从Plate接口实现来的, set(Ljava/lang/Comparable)V 是他本身的,因为限定了类型范围

上边我们是通过showbytecode的方式查看的字节码,但是如果你点开类生成的class文件,你会发现,泛型既然被擦除了为什么在class中仍然可以看到?其实这里看到的只是签名而已,还保留了定义的格式,这样对分析字节码有好处。你甚至可以通过javap -c Plate2.class反编译class,你会发现,R还是能被看到,我们要看bytecode,通过showbytecode的方式比较真实

比如没有ArrayList<int>,只有ArrayList<Integer>.当类型擦除后,ArrayList的原始类中的类型变量(T)替换成Object,但Object类型不能 存放int值

因为擦除后,ArrayList<String>只剩下原始类型,泛型信息String不存在了,所有没法使用instanceof

因为泛型类中的泛型参数的实例化是在定义泛型类型对象 (比如ArrayList<Integer>)的时候指定的,而静态成员是不需要使用对象来调用的,所有对象都没创建,如何确定这个泛型参数是什么

因为擦除后两个equals方法变成一样的了

因为类型不确定

因为数组是协变( 在某些情况下,即使某个对象不是数组的基类型,我们也可以把它赋值给数组元素。这种属性叫做协变(covariance) ),擦除后就没法满足数组协变的原则


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11912490.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存