泛型本质就是参数化类型,也就是所操作的数据类型被指定为一个参数。
这种参数类型可以用在 类、接口和方法 中,分别被称为 泛型类、泛型接口和泛型方法
1)泛型类
基本语法
class 类名称 <泛型标识,泛型标识,…> {
private 泛型标识 变量名;
.....
}
复制代码
使用示例
class Result<T>{
private T data;
}
复制代码
注:
- Java 1.7 之后可以进行类型推断,后面 <> 中的具体的数据类型可以省略不写:
类名<具体的数据类型> 对象名 = new 类名<>();
复制代码
- 如果我们使用的时候没有用到
<>
来制定数据类型,那么操作类型则是Object
- 泛型内的类型参数只能是
类
类型,而不能是基本数据类型,例如int,double,float...
- 当我们传入不同数据类型进行构造对象时,逻辑上可以看成是多个不同的数据类型,但实际上都是相同类型
以上便是泛型类的简单用法,我们想要使用哪种类型,就在创建的时候指定类型,使用的时候,该类就会自动转换成用户想要使用的类型。
那么如果我们定义了一个泛型类,构造对象的时候却没有声明数据类型,那么默认为 Object
类型,取出数据的时候则需要进行类型转换:
Result objectRes = new Result("testObejct");
String str = (String) objectRes.getData();
System.out.println(str);
复制代码
规则:
- 子类也是泛型类,那么子类和父类的泛型类型要一致
public class ResultChild<T> extends Result<T> {}
复制代码
- 子类不是泛型类,那么父类要指定数据类型
public class ResultChild extends Result<String> {}
复制代码
2)泛型接口
基本语法
public 接口名称 <泛型标识, 泛型标识, ...>{
泛型标识 方法名();
...
}
复制代码
使用示例
public interface ResultInterface<T> {
T getData();
}
复制代码
泛型接口与泛型类一样,有以下规则:
- 实现类不是泛型类,接口要明确数据类型
- 实现类也是泛型类,实现类和接口的泛型类型要一致
3)泛型方法
在 Java 中,泛型类和泛型接口的定义相对比较简单,但是 泛型方法 就比较复杂。
- 泛型类,是在实例化类的时候指明泛型的具体类型
- 泛型方法,是在调用方法的时候指明泛型的具体类型
基本语法
修饰符 <T, E, ...> 返回值类型 方法名(形参列表){}
复制代码
-
修饰符与返回值类型之间的
<T>
用于声明此方法为泛型方法 -
只有声明了
<T>
的方法才是泛型方法,就算返回值类型中的泛型类使用泛型的成员方法也并不是泛型方法 -
<T>
表明该方法将使用泛型类型 T,此时才可以在方法中使用泛型类型 T
使用示例
private <T> Result<T> getResult(T data) {
return new Result<T>(data);
}
复制代码
泛型方法与可变参数:
private <T> void printData(T... data) {
for (T t : data) {
System.out.println(t);
}
}
复制代码
注:
- 泛型方法能使方法独立于类而产生变化
- 如果 静态(static) 方法 要使用泛型能力,就必须使其成为泛型方法
https://juejin.cn/post/6900497265048158215