Java泛型(Generics),JDK5引入的新特性。泛型参数能增强代码的可读性和稳定性。
编译器可以对泛型参数进行检测,通过泛型参数可以指定传入对象的类型,比如ArrayList<People> list = new ArrayList<>();指定只能传入People对象,否则报错。
以下是分类:
泛型类
public class Person<T> {
private T key;
public Person(T key){
this.key = key;
}
}
实例化:
Person<String> stringPerson = new Person<>("王大壮");
泛型接口
public interface Person<T> {
public T method();
}
接口的作用就是被实现,泛型接口可以有两种实现方式。
不指定泛型
public class Peron1Impl<e> implements Person<e>{
@Override
public e method() {
return null;
}
}
指定泛型
public class Person2Impl implements Person<String>{
@Override
public String method() {
return null;
}
}
泛型方法
public static <E> void print(E[] a){
for (E e : a) {
System.out.println(e);
}
}
这样的方法称为静态泛型方法,泛型在java中只是一个占位符,必须在传递类型后可以使用,但是静态方法比类的实例化加载的早,所以静态泛型方法没法使用类声明的泛型,所以只能使用自己声明的泛型。
区分泛型方法:用的是不是自己声明的泛型
public class Person<T> {
// 不是泛型方法
public T print(T t){
System.out.println(t);
return t;
}
// 是泛型方法
public static <T> T print2(T t){
System.out.println(t);
return t;
}
}
应用案例:
先定义三个类,Teacher和Worker都是Person的子类
public class Person {
String name;
}
public class Teacher extends Person{
}
public class Worker extends Person{
}
我需要写一个方法,这个方法能接收这三个类型的ArrayList集合,这时候就可以用到泛型方法。
public class Test {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<>();
list.add(new Teacher());
list.add(new Worker());
print(list);
ArrayList<Person> teachers = new ArrayList<>();
teachers.add(new Teacher());
teachers.add(new Teacher());
print(teachers);
ArrayList<Person> workers = new ArrayList<>();
workers.add(new Worker());
workers.add(new Worker());
print(workers);
}
public static <T> void print(ArrayList<T> a){
for (T t : a) {
System.out.println(t);
}
}
}
但是应该限制内容,总不能什么ArrayList集合都接受吧,可以用另一种写法。
public static void print(ArrayList<? extends Person> a){
for (Person p : a) {
System.out.println(p);
}
}
?代表通配符
? extends Person代表接收的必须是Person或者Person的子类
? super Person代表接收的必须是Person或者Person的父类