Java泛型类的继承关系
来源:互联网 发布:建筑电气常用数据 编辑:程序博客网 时间:2024/06/06 07:24
引言
类型兼容的对象可以进行赋值,如可将一个 Integer 对象传给一个 Object 对象,因为 Object 是 Integer 的基类。
Object someObject = new Object();Integer someInteger = new Integer(10);someObject = someInteger; // OK
对于方法的参数,也可传递类型兼容的对象。如 Integer 是一个 Number ,故如下代码可正确执行。
public void someMethod(Number n) { /* ... */ }someMethod(new Integer(10)); // OKsomeMethod(new Double(10.1)); // OK
类型兼容不能直接运用到泛型类型上,考虑如下方法:
public static void boxTest(Box<Number> box) { System.out.println(box.get());}
该方法接受类型为 Box<Number>
的参数,那么该方法是否接收类型为 Box<Integer>
或 Box<Double>
的参数?要回答这个问题,首先要清楚以下两个问题:
1. boxTest
的字节码签名是什么?
2. Box<Number>
的子类型应满足什么条件?
1. BoxTest的字节码签名
这个话题涉水较深,如果使用 javap -s -c, 只能看到 descriptor 的信息:
public static void boxTest(generic.inheritance.Box<java.lang.Number>);descriptor: (Lgeneric/inheritance/Box;)VCode: 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: aload_0 4: invokevirtual #3 // Method generic/inheritance/Box.get:()Ljava/lang/Object; 7: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 10: return
由上面的信息只能推导出 boxTest 只接受类型为 Box 的参数。而 Box 是泛型类,其基类为 Object. 需要使用 javap -v 才能确定 boxTest 完整签名信息:
public static void boxTest(generic.inheritance.Box<java.lang.Number>);descriptor: (Lgeneric/inheritance/Box;)Vflags: ACC_PUBLIC, ACC_STATICCode: stack=2, locals=1, args_size=1 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: aload_0 4: invokevirtual #3 // Method generic/inheritance/Box.get:()Ljava/lang/Object; 7: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 10: return LineNumberTable: line 11: 0 line 12: 10Signature: #19 // (Lgeneric/inheritance/Box<Ljava/lang/Number;>;)V
Signature: #19
才是 boxText
的完整签名信息,表示该方法之接受类型为泛型类型 Box<Number>
的参数。接下来确定 Box<Number>
的子类型。
2. 泛型类的子类型
泛型类或接口的子类型创建方式与创建常规的类或接口的子类型创建方式一致,即使用 extends 或 implements 关键字。
以 Collections 为例,ArrayList<E>
实现了 List<E>
, 同时 List<E>
扩展自 Collections<E>
. 故 ArrayList<E>
是 List<E>
的子类型,List<E>
是 Collections<E>
的子类型。只要类型参数 E 一致,这三个类的继承关系就得到保持。
由于 Box<Number>
和 Box<Integer>
的类型参数不同,故两者没有继承关系,其关系可如下表示:
因此, testBox(Box<Number>)
不接收类型为 Box<Integer>
和 Box<Double>
的参数。
小结
对于类 A 和类 B, MyClass<A>
和 MyClass<B>
没有任何继承关系,即使 A 是 B 的子类。MyClass<A>
和 MyClass<B>
的共同子类为 Object.
拓展:包含额外类型参数的继承关系
对于自定义的列表接口, PlayloadList 包含了一个额外的类型参数 P, 表示列表中的每个元素都关联了类型为 P 的元素。设存在方法:
interface PayloadList<E,P> extends List<E> { void setPayload(int index, P val); ...}
以下的三个 PayloadList 都是 List<String>
的子类:
- PayloadList
<String,String>
- PayloadList
<String,Integer>
- PayloadList
<String,Exception>
继承关系如下所示:
- Java泛型类的继承关系
- JAVA的继承关系
- Java继承关系的判断
- java Swing的继承关系
- 学习JAVA继承关系很好的例子
- Java中继承关系的实例分析
- Java继承时构造函数的关系
- Java -- 继承和实现接口的关系
- 理解java.io的类继承关系
- Java类集(接口继承的关系)
- Java继承,组合,聚合的关系
- Java中的继承关系的加载顺序
- Java继承关系构造函数的调用
- Java之类之间的继承关系
- Java泛型与继承的关系
- java实现接口与继承的关系
- Java集合类的继承关系
- 【奔跑的菜鸟】Java中的继承关系
- 服务器黑白名单配置
- 5.7
- Move Zeroes
- 把握他人需求的心理策略
- ioctl()函数详解
- Java泛型类的继承关系
- eclipse下安装pdt进行php项目
- Activity的四种launchMode
- 你和“肿瘤君”有多亲密?
- 【leetcode】【88】Merge Sorted Array
- MFC隐藏主窗口的方法
- android 开发技巧(14)--通过ViewHolder优化适配器
- 分布式系统的事务处理经典问题及模型
- Outlook PST异常修复