目录
泛型的向上转型
将静态方法的泛型类型和实例类型的泛型类型区分开
多泛型类
java可以创建泛型数组(待完善)
Java实现泛型的方法——擦拭法
由此,Java泛型的局限也体现出来
泛型继承(loading)
通配符(loading)
泛型与反射(loading)
总结自廖雪峰老师的Java教程:
Java教程 - 廖雪峰的官方网站 (liaoxuefeng.com)https://www.liaoxuefeng.com/wiki/1252599548343744
泛型的向上转型
在Java标准库中, ArrayList
public class ArrayListimplements List { ... } List list = new ArrayList ();
编译器看到泛型类型List
// 可以省略后面的Number,编译器可以自动推断泛型类型: Listlist = new ArrayList<>();
!注意:不能把ArrayList
假设ArrayList
// 创建ArrayList类型: ArrayList integerList = new ArrayList (); // 添加一个Integer: integerList.add(new Integer(123)); // “向上转型”为ArrayList : ArrayList numberList = integerList; // 添加一个Float,因为Float也是Number: numberList.add(new Float(12.34)); // 从ArrayList 获取索引为1的元素(即添加的Float): Integer n = integerList.get(1); // ClassCastException!
- 一个ArrayList
转型为ArrayList 类型后,这个ArrayList 就可以接受Float类型,因为Float是Number的子类。 - 而numberList 实际上和integerList 是同一个对象(ArrayList
类型),不可能接受Float类型, 在获取Integer的时候将产生ClassCastException。
总结:
编译器为了避免这种错误,根本就不允许把ArrayList
转型为ArrayList 。 !注意泛型的继承关系:可以把ArrayList
向上转型为List (T不能变),但不能把ArrayList 向上转型为ArrayList (T不能变成父类) ▲另外须知: ArrayList
和ArrayList 两者完全没有继承关系。
将静态方法的泛型类型和实例类型的泛型类型区分开
注意,泛型类型不能用于静态方法
下面的代码编译错误
public class Pair{ private T first; private T last; public Pair(T first, T last) { this.first = first; this.last = last; } public T getFirst() { ... } public T getLast() { ... } // 对静态方法使用 : public static Pair create(T first, T last) { return new Pair (first, last); } }
正确表示如下
public class Pair{ private T first; private T last; public Pair(T first, T last) { this.first = first; this.last = last; } public T getFirst() { ... } public T getLast() { ... } // 静态泛型方法应该使用其他类型区分: public static Pair create(K first, K last) { return new Pair (first, last); } }
多泛型类
class Pair{ private T first; private K second; public Pair(T first, K second){ this.first = first; this.second = second; } public T getFirst(){ return this.first; } public K getSecond(){ return this.second; } } public class pairx { public static void main(String[] args) { Pair p1 = new Pair<>("泥烟", 8080); System.out.println(p1.getFirst()+p1.getSecond()); } }
运行结果:
输出→ 泥烟8080
另外java是可以创建泛型数组的(还未完全掌握,之后完善):
java可以创建泛型数组(待完善)Java中创建泛型数组 - minghai - 博客园 (cnblogs.com)https://www.cnblogs.com/minghaiJ/p/11259318.html
Java实现泛型的方法——擦拭法Java的泛型是由编译器在编译时实行的,编译器内部永远把所有类型T视为Object处理,但是,在需要转型的时候,编译器会根据T的类型自动为我们实行安全地强制转型。
由此,Java泛型的局限也体现出来泛型继承(loading) 通配符(loading) 泛型与反射(loading)局限一:
不能是基本类型,例如int,因为实际类型是Object,Object类型无法持有基本类型: Pairp = new Pair<>(1, 2); // compile error! 局限二:无法取得带泛型的Class
有如下类
class Pair{ private T first; private T last; public Pair(T first, T last) { this.first = first; this.last = last; } public T getFirst() { return first; } public T getLast() { return last; } } Pairp1 = new Pair<>("Hello", "world"); Pair p2 = new Pair<>(123, 456); Class c1 = p1.getClass(); Class c2 = p2.getClass(); System.out.println(c1==c2); // true System.out.println(c1==Pair.class); // true
无论T的类型是什么,getClass()返回同一个Class实例,因为编译后它们全部都是Pair
局限三:无法判断带泛型的类型,原因同上
Pairp = new Pair<>(123, 456); // Compile error: if (p instanceof Pair ) { ... } 并不存在Pair
.class,而是只有唯一的Pair.class 局限四:不能直接实例化T类型
public class Pair{ private T first; private T last; public Pair() { // Compile error: first = new T(); last = new T(); } } 擦拭后实际上变成了: first = new Object(); last = new Object(); 将其实例化的方法
(待续...)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)