泛型
概述
泛型,即“参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
使用
泛型类
//定义一个泛型类
public class Person<T> { //在类名后加上参数<T>
private T data; //类中的参数和方法类型也用参数代替
public T getData(){
return data;
}
public void setData(T data){
this.data = data;
}
}
//该类的调用
public class Demo1 {
public static void main(String[] args) {
Person<Integer> person = new Person<>();
person.setData(1); //括号中的数据只能为int类型数据
}
}
泛型接口
//接口定义
public interface InterfaceName<T> {
T getData();
}
实现接口时,可以选择指定泛型类型,也可以选择不指定, 如下:
指定类型:
public class Interface1 implements InterfaceName<String>{
//接口名称后指定类型为String
private String text; //设置相关变量也需设置成和调用方法同类型
@Override
public String getData() {
//方法名前的类型T 也指定为String
return text;
}
}
不指定类型:
public class Interface1<T> implements InterfaceName<T> {
//类名不指定类型,为Interface1<T> ,接口也不指定类型,为 InterfaceName<T>
private T text; //相关变量定义时不指定类型
@Override
public T getData() { //方法不指定类型
return text;
}
}
泛型方法
格式:
private static <T> T 方法名(T a, T b) {}
例子:
public class Demo1 {
public static void main(String[] args) {
//方法类型为void,无返回值,故调用方法时,方法名前无需加任何数据类型定义
print(123); //直接输入123 ,自动识别为Integer类型
print("String:abc"); //采用此格式输入String类型数据
print("abc"); //也可以采用这种方式来进行输入String类型数据
//双引号内的数据全部输出
}
public static <T> void print(T a){ //a只在方法内部有效
System.out.println(a);
}
}
输出结果为:
123
String:abc
abc
泛型限制类型
1. 在使用泛型时, 可以指定泛型的限定区域 ,
- 例如: 必须是某某类的子类或 某某接口的实现类,
格式: <T extends 类或接口1 & 接口2>
例1:
public class Demo2 {
public static void main(String[] args) {
Plate<Fruit> p1 = new Plate<>(); //不能这么设置
Plate<Apple> p2 = new Plate<>();
//Plate方法类型受限制,只能为Fruit的子类类型
}
}
interface Fruit{}
class Apple implements Fruit{}
class Plate<T extends Fruit>{ //T为Fruit的子类类型
//对泛型进行区域性限制
T data;
}
例2:
public class Demo2 {
public static void main(String[] args) {
//不能将装着苹果的盘子,看作一个装着水果的盘子
//<>中的数据为父子关系,不能这么使用
// Plate<Fruit> p1 = new Plate<Apple>();
//需改成如下
Plate<? extends Fruit> p1 = new Plate<Apple>();
//上界限定
Plate<? super Apple> p2 = new Plate<Fruit>();
//下界限定
}
}
interface Fruit{}
class Apple implements Fruit{}
class Plate<T>{
T data;
}
泛型中的通配符
类型通配符是使用?代替方法具体的类型实参。
1、 <? extends Parent> 指定了泛型类型的上界
2 、<? super Child> 指定了泛型类型的下界
3 、<?> 指定了没有限制的泛型类型,可以当作Object来使用,使用起来有区别,当定义过一次之后只能为此类型了,后续不能定义为其他类型
作用
1、 提高代码复用率
2、 泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)
注意
1、在编译之后程序会采取去泛型化的措施。
2、也就是说Java中的泛型,只在编译阶段有效。
3、在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段。