泛型的定义
为什么需要泛型
当我们进行一些和类型无关的计算的时候,例如:排序、二分查找等算法。或者类似的场景的时候,允许算法中的一个或者多个类型变化起来(——类型变量)。
例如:定义了一个int型的排序算法,那么它只能排序int型的,对于double、String型都无法实现。
引入泛型
Java中引入泛型的原因:
- Object引用可以指向Java中所有的类型的对象
- 在Object的基础上继续发展,发展出了泛型
Java中的泛型只针对引用类型 不针对基本类型
泛型的概念
Java1.5新增的特性,通过泛型可以写与类型无关紧要的的代码,即编写的代码可以被很多不同类型的对象重用,在一些通用代码中实现。
泛型在Java中最大的特点就是 < >,当我们看见了尖括号(成对的),就往泛型上找
泛型类的定义
class 泛型类的名称 <类型形参列表> {
//这里可以使用参数类型
}
class ClassName<T1 ,T2,...Tn> {
//实现类体
}
例如:
public static <T> int method(T[] arr,T tar){
return -1;
}
使用:
String[] arr ={
"hello","world"};
int r=Method.<String>method(arr,"world");
Integer [] arr2 ={
1,2,3,4};
int r=Method.<Integer>method(arr,"world");
注意:Java中的泛型只针对引用类型 不针对基本类型
泛型类的实例化
泛型类<类型实参>变量名;定义一个泛型类引用。new 泛型类<类型实参>(构造方法实参);实例化一个泛型类对象。
注意:
1、右侧<>中的类型可以省略
MyMethod<String> m = new MyMethod<>(10);
在new MyMethod<>(10)对象时,<>中未明确指明类型,编译器会根据=左侧<>中的类型来推演。
2、左侧<>中的类型不能省略
MyMethod<> m = new MyMethod<String>(10);//编译失败
编译器的推演是根据左侧类型来推演右侧的。
3、虽然右侧<>可以不用写类型,但是<>不能省略
MyMethod<> m = new MyMethod(10);//警告
会发生警告
泛型接口
例如:
实现Comparable接口
public class Demo implements Comparable<Demo> {
@Override
public int compareTo(Demo o) {
return 0;
}
}
通配符-上下界
上界:
语法:
<? extends 上界>
Object是所有类的父类,当不使用extends时默认的上界是Object,当使用extends继承后,继承自那个,那个就是上界。
下界:
语法:
<? super 下界>
即:指向的那个父类,就是它的下界,上面的都可用
类型擦除
Java泛型的这个特性是在JDK1.5后加入,Java的语法上支持泛型,但在编译阶段会进行类型擦除,将所有的泛型表示,(尖括号中的内容)替换成其对应的原生类型,就如同没有泛型一样。
规则
- 消除类型参数声明,即删除<>中及其包围的部分
- 根据类型参数的上下界推断并替换所有的参数类型的原生类型