Java基础知识-泛型
我将从以下几个方面总结泛型知识点:
一、概念
泛型的本质就是参数化类型(就是说所操作的数据类型被指定为一个参数),这种参数类型可以用在类上、接口和方法上,分别被称为泛型类、泛型接口和泛型方法。其实就是一句话,将具体的类型用参数表示。以前,我们定义一个方法,可能要事先定义好方法的返回值类型,方法的入参参数类型。有了泛型之后就不用了。统统用参数来表示类型。这样做的好处就是方法更通用了。
二、定义
2.1 泛型接口的定义
格式: public interface 接口名<泛型类型>{}
public interface TestFanXingI<T> {
T get(T t);
}
2.2 泛型类的定义
格式: public class 类名<泛型类型> {}
// 定义一个物品的泛型类
class WuPingClass<T> {
private T wpName;
public WuPingClass() {
}
public WuPingClass(T wpName) {
this.wpName = wpName;
}
/**
* 这个方法不能称之为泛型方法,只能说返回值是一个泛型类型
*/
public T getWpName() {
return wpName;
}
public void setWpName(T wpName) {
this.wpName = wpName;
}
}
2.3 泛型方法的定义
格式: public <泛型类型> 返回类型 方法名(泛型类型 变量名) {}
public class WuPingClass<T> {
public <T> T fanXingMethodName(T t) {
return t;
}
}
这里一定要注意 “泛型类型”,也叫泛型形参,这是泛型方法与普通方法最能区分的一个标志。可以直接用来区分一个方法是否是泛型方法。
三、泛型通配符及界限
泛型通配符如下:
E: Element(在集合中使用,因为集合中存放的是元素)
T: Type(Java类)
K: Key(键)
V: Value(值)
N: Number(数值类型)
?: 表示不确定的Java类型
以上这些知识标准,规范化的定义。我们不遵守也罢。
通配符界限我们也要注意,这个通配符界限只能与泛型一起使用,是依赖泛型的。主要是对入参做限制。有以下三种,分别如下:
- <?> : 任意通配符 (对入参没有限制)
- <? extends class> : 上界通配符(入参是本身或者自己的子类)
- <? super class> : 下界通配符 (入参是本身或者自己的父类)
以上这些限制都只是在编译阶段,因为泛型只是在编译阶段生效,最终我们在机器运行的代码都是去泛型化后的代码,去泛型化也叫擦除泛型。
代码示例:
private static <T> void testExtends(List<? extends Father> list) {
Optional.of(list).ifPresent(System.out::println);
}
private static <T> void testSuper(List<? super Dauther> parms) {
Optional.of(parms).ifPresent(System.out::println);
}
private static <T> void testWu(List<?> parms) {
Optional.of(parms).ifPresent(System.out::println);
}
四、泛型使用的注意事项
4.1 静态方法中定义放行方法
/**
* 如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明(将这个方法定义成泛型方法)
* 即使静态方法要使用泛型类中已经声明过的泛型也不可以。
* 如:public static void show(T t){..},此时编译器会提示错误信息:
"StaticGenerator cannot be refrenced from static context"
*/
public static <T> void show(T t){
}
4.2 泛型方法与可变参数
public <T> void printMsg( T... args){
for(T t : args){
Log.d("泛型测试","t is " + t);
}
}
五、总结
关于泛型的总结我只想说一定要理解 “类型参数化” 这五个字,拿泛型方法来总结一下:
public T fanXingMethodName(T t) {} 其中,这个方法的返回值类型是T,入参也是T, T也叫类型形参,具体这个类型在由调用着传入,而 称为类型形参声明,声明后就可以在方法中使用,这里不一定要声明成T,可以是任意字母。