15.2 简单泛型
在没有泛型之前,采用的是继承机制来实现泛型,但是需要强制类型转换,会有风险
创建泛型类:
1 | public class A<T>{ |
15.2.1 使用泛型创建多维元祖,实现一次调用返回多个对象
1 | public class Tuple<A,B,C,...>{//A,B,C是泛型 |
15.3 泛型接口
public interface Generator<T> {T next();}
实现接口:
1 | public class A implements Generator<Integer>{ //指定泛型T具体类型,可以是包装类数据类型也可以是自定义类 |
15.4 泛型方法
为什么要用泛型方法?
- 因为泛型类要在实例化的时候就指明类型,如果想换一种类型,不得不重新new一次,可能不够灵活;而泛型方法可以在调用的时候指明类型,更加灵活
- 使用泛型类,创建对象时必须指定泛型具体类型;而使用泛型方法,则不必指定,编译器会根据参数自动判断
泛型方法定义
泛型参数列表必须置于返回值之前前,泛型方法的类可以是泛型类也可以不是
public <T> void f(T x){...}
public <T,E> E f(T a, E b) {...}
public static <T> T f(T a){}
//泛型静态方法定义
显式指定类型调用泛型方法
1 | public class A{ |
15.7 擦除
什么是擦除:
泛型具体类型不同擦除后会变成原生类 如List
和List 是一种类型,最后都会擦除成List 泛型只是用来检查类型正确性,一旦运行就会被擦除
擦除的结果:
List<T>
被擦除为List
、List<String>
被擦除为List<Object>
<T extends A>
擦除为<A>
什么是边界:
- 运行后泛型会被擦除到上边界
class A<T extends B>
擦除到<B>