本文内容是泛型的梳理和总结,本文内容包括:
什么是泛型:泛型是指数据类型可变
Java 泛型(Generics) 是 JDK 5 中引入的一个新特性。使用泛型参数,可以增强代码的可读性以及稳定性。
编译器可以对泛型参数进行检测,并且通过泛型参数可以指定传入的对象类型。
public class StudentManager {
String field;
public String get() {
return this.field;
}
}
分析:
如果在开发中数据的类型要求是可以变化的,例如field的类型可能是String,也可能是Integer,怎么实现?
使用泛型可以实现吗,==泛型就是让类型可变==
泛型有三类
接口中方法的返回值类型由子类确定。
//子类实现泛型接口时,必须指定T的具体类型
public interface IStudent<T> {
public T get();
}
public class Graduate implements IStudent<Graduate>{
@Override
public Graduate get() {
return new Graduate();
}
}
public class UnderGraduate implements IStudent<UnderGraduate> {
@Override
public UnderGraduate get() {
return new UnderGraduate();
}
}
泛型通常使用一个大写字母表示,例如T,E
泛型的实际类型是子类或者调用时,由子类或调用者传入实际类型。
下图是泛型接口中类型传入流程示意图
类中属性类型、方法参数类型、方法返回值类型由调用者确定。
//在实例化泛型类时,必须指定T的具体类型
public abstract class Worker<E> {
public abstract E get(E e);
}
public class Driver extends Worker<String> {
@Override
public String get(String e) {
return null;
}
}
public class Doctor extends Worker<Integer>{
@Override
public Integer get(Integer e) {
return null;
}
}
下图是泛型类中类型传入流程示意图
public class Person {
public <E,T> T get(E e) {//<E,T>是泛型方法的特征,写在方法返回值前面
return null;
}
public <T> void set(T e) {//<T>是泛型方法的特征,写在方法返回值前面
}
public static void main(String[] args) {
Person p =new Person();
// 在.和方法名之间传入泛型的类型
Integer i = p.<String,Integer>get("abc");
Double d = p.<Object,Double>get("abc");
//<String>是调用泛型方法时传入泛型的具体类型
p.<String>set("abc");
//调用泛型方法时,如果不传入泛型的具体类型,泛型方法也能根据传入参数的类型推断出泛型的类型为String
//本例中,通过方法参数"abc"推断出T为String类型,推荐这种调用方式
p.set("abc");
}
}
下图是泛型方法中类型传入流程示意图
public class GenericTypes {
public static void method(List<String> list) {
System.out.println("invoke method(List<String> list)");
}
public static void method(List<Integer> list) {
System.out.println("invoke method(List<Integer> list)");
}
}
上面这段代码,有两个重载的函数,因为他们的参数类型不同,一个是List<String>
另一个是List<Integer>
,但是,这段代码是编译通不过的。因为参数List<Integer>
和List<String>
编译之后都被擦除了,变成了一样的原生类型 List,擦除动作导致这两个方法的特征签名变得一模一样。
集合是泛型使用最常见的场景,例如
List<Integer> list = new ArrayList();
powered by kaifamiao