九、泛型
List<String> list=new ArrayList<String>();
// JaveSE 7 以后的版本 后面构造函数里的 String 可以省略
List<String> list2=new ArrayList<>();
尽量不要写这种有能与泛型方法重载的代码,有迷惑性
package org.example;
public class Genericity<T> {
public static String prU(String s){
System.out.println("普通方法"+s);
return null;
}
public static <U> U prU (U u){
System.out.println("泛型方法"+u);
return null;
}
public static void main(String[] args) {
Genericity.prU(6);
Genericity.prU("string");
Genericity.<String>prU("string");
}
}
// 打印结果
// 泛型方法6
// 普通方法string
// 普通方法string
限定传入 T 的类型
//
// Java 是单继承类,多实现接口,所以 T 最多能被限定为一个类的子类,可以限定为实现多个接口
// 限定 T 是 xx 的子类,这个 xx 要放在最前面,类和多个接口之间用 & 分隔
// 多个泛型类之间用 , 隔开
public class Genericity<T extends Animal & Comparable &Serializable, S extends Person> {
}
泛型数组
Java 不支持泛型类型的数组
通配符
Pair<? super Employee> pair :带有超类型限定的通配符可以向泛型对象写入
Pair<? extends Employee> pair :带有子类型限定的通配符可以从泛型对象读取
Pair<?> pair :无限定通配符 get返回值只能赋给 Object , set 方法不能被调用
package org.example;
import org.example.domain.Employee;
public class Pair<T> {
T first;
T second;
/// 这里解释的有些混乱 ,下面还有一个解释
// 传入参数 pair 的泛型 T 是 Employee 的子类, pair.getFirst 将返回一个 Employee 的子类 T ,可以用 Employee类型接收 ,也因此能使用 Employee 的方法
// 但是 setFirst( T ) 的参数需要传入一个 T 的子类,无法保证
static void print(Pair<? extends Employee> pair){
// 比如传入了参数是这样声明的 Pair<EmployeeSon> pair = new Pair<>();
// 那么 get方法的声明就会变成 EmployeeSon getFirst()
Employee e=pair.getFirst();
e.getName();
// 那么 set方法的声明就会变成 void setFirst( EmployeeSon e)
// 但是你无法提前预知 EmployeeSon ,没法保证传入的就一定是 EmployeeSon 的子类
// pair.setFirst( xxx )
}
// 传入参数 pair 的泛型 T 是 Employee 的父类
// setFirst(T ) 只要传入 Employee 及子类,则一定能满足条件
// 但是 getFirst() 的返回值为类 T ,只有最高的 Object o= T()
static void print2(Pair<? super Employee> pair){
// 比如传入的参数是这样声明的 Pair<EmployeeFather> pair = new Pair<>();
// 那么 set方法的声明就会变成 void setFirst( EmployeeFather e)
pair.setFirst(new Employee());
// 那么 get方法的声明就会变成 EmployeeFather getFirst()
// 但是你无法提前预知 EmployeeFather ,没法保证用来接收的类一定是EmployeeFather的父类,除了 Object类
// Employee e= pair.getFirst(); // 返回的是 EmployeeFather 类型 会出错
// 虽然接收了,但是后续拿来干什么?没有意义
Object o=pair.getFirst();
}
//
static void print3(Pair<?> pair){
//pair.setFirst(new Object()); // 出错 set 方法不能调用
//pair.setFirst(new EmployeeSon()); // 出错
//Employee e= pair.getFirst(); // 返回的 Object 类型 会出错
}
public static void main(String[] args) {
Pair<Object> pair = new Pair<>();
print(pair); // 报错
print2(pair);
Pair<EmployeeSon> pair2 = new Pair<>();
print(pair2);
print2(pair2); // 报错
}
public T getFirst() {
return first;
}
public void setFirst(T first) {
this.first = first;
}
public T getSecond() {
return second;
}
public void setSecond(T second) {
this.second = second;
}
}
? super ?extends 看这里 ↓↓↓↓↓↓↓↓↓
static void print(Pair<? extends Employee> pair){
T t1=pair.getFirst();
// 因为 T 是 Employee 的子类,所以下面的代码是没问题的
Employee e=t1;
e.getName();
// 这里 A 类需要是 T 的子类,需要找到一个具体的类A,确保 A 一定是 T 的子类,
// 没有办法保证,所以无法使用 set 方法
T t2=new A();
pair.setFirst(t2 )
}
static void print2(Pair<? super Employee> pair){
// T 是 Employee 的父类,所以下面的代码一定没问题
T t1= new EmployeeSon();
pair.setFirst(t1);
T t2=pair.getFirst();
// 需要 A 是 T 的父类,需要找到一个具体类 A,确保 A 是 T 的父类,
// 无法保证,除了 Object 类,
// 用 Object 接收了也没什么意义,所以说无法使用 get 方法
A a=t2;
}
网友评论