Java中的泛型是1.5版本引入的,功能有点类似于C++ 的模板,模板是C++支持参数化多态的工具,目的就是让代码更加通用化,一套模板多次使用,模板分为类模板和函数模板,就是作用在类或者函数上。那么Java也是如此,Java的泛型作用在类(接口)或者方法上。
1.泛型类(接口) 在实例化的时候指定具体类型
// 定义一个泛型类 指定有哪些类型用 K E T 参数为标识 可以任意写多个
public class Person<K, E, T> {
// 属性的类型则就由类的参数类型 指定
private K attribute1;
private E attribute2;
private T attribute3;
public Person(K attribute1, E attribute2, T attribute3) {
this.attribute1 = attribute1;
this.attribute2 = attribute2;
this.attribute3 = attribute3;
}
public K getAttribute1() {
return attribute1;
}
public void setAttribute1(K attribute1) {
this.attribute1 = attribute1;
}
public E getAttribute2() {
return attribute2;
}
public void setAttribute2(E attribute2) {
this.attribute2 = attribute2;
}
public T getAttribute3() {
return attribute3;
}
public void setAttribute3(T attribute3) {
this.attribute3 = attribute3;
}
@Override
public String toString() {
return "Person{" +
"attribute1=" + attribute1 +
", attribute2=" + attribute2 +
", attribute3=" + attribute3 +
'}';
}
public static void main(String[] args) {
Person<Integer, String, Double> person = new Person<>(1, "zhangsan", 20.);
Person<String, Double, Integer> person2 = new Person<>("lisi", 22., 2);
System.out.println(person);
System.out.println(person2);
//Person{attribute1=1, attribute2=zhangsan, attribute3=20.0}
//Person{attribute1=lisi, attribute2=22.0, attribute3=2}
}
}
//定义一个泛型接口
public interface Person<K, E> {
E exec(K k);
}
// 实现类实现泛型接口的时候 可以指定泛型接口的实参类型
public class Giant implements Person<Integer, String> {
@Override
public String exec(Integer key) {
return "qwer" + key;
}
public static void main(String[] args) {
Giant giant = new Giant();
System.out.println(giant.exec(123));
;
//qwer123
}
}
2.泛型方法 在方法调用的时候指定具体类型
泛型方法的写法是 修饰符之后 方法名之前,<T> 其中T可以随意写
public <T> void calc(T value) {
System.out.println(value);
}
// 也可以定义多个泛型参数
public <T, E> void calc(T value, E value2) {
System.out.println(value);
System.out.println(value2);
}
静态方法则是 static修饰符之后 方法名之前
public static <T> void exec(T t) {
}
如果静态方法参数想用类的泛型参数,那必须得加<T> ,普通方法则不用
// 会提示this cannot be referenced from a static context
public static void exec(T t) {
}
public void exec2(T t) {
}
3.泛型类的上下边界
比如泛型参数类型指定某类型的子类
// 定义一个父类
@Data
public class Parent {
private Long id;
}
// 定一个子类
@Data
public class Child extends Parent {
private String name;
}
//定义泛型参数继承 Parent
public class Person<T extends Parent> {
private T t;
public Person(T t) {
this.t = t;
}
// 可以获取Parent类的id属性
public void exec() {
System.out.println(t.getId());
}
public static void main(String[] args) {
Child child = new Child();
child.setId(1L);
child.setName("zhangsan");
Person<Child> person = new Person<>(child);
person.exec();
}
}
方法中指定上下边界
public class Person<T> {
// 上边界
public void exec(Person<? extends Parent> person) {
}
// 下边界
public void exec2(Person<? super Child> person) {
}
}