泛型
类中的泛型
public class Person<A> {
private String name;
private int age;
private A data;
...
public A getData() {
return data;
}
public void setData(A data) {
this.data = data;
}
}
public class Demo1 {
public static void main(String[] args) {
Person<String> p = new Person<>();
p.setData("123");
}
}
接口中的泛型
public interface Function<T> {
T a();
}
实现时可以指定或不指定泛型:
// 指定
public class Imp implements Function<String>{
@Override
public String a() {
return null;
}
}
// 不指定
class Imp2<T> implements Function<T>{
@Override
public T a() {
return null;
}
}
方法中的泛型
public class Fx {
// 泛型声明<T>,该泛型只能在方法中使用
// 参数包含T泛型:
public <T> void abc(T a){
return;
}
// 返回值为T泛型:
public <T> T asd(){
T a = null;
return a;
}
}
泛型限制类型
public class Demo2 {
public static void main(String[] args) {
// 需求:盘子里面只能放水果,泛型限制:
Plate<Fruit> fruitPlate = new Plate<>();
}
}
interface Fruit{}
class Apple implements Fruit{}
// 盘子类,使用 extends 限制泛型
class Plate<T extends Fruit>{
T[] data;
}
泛型通配符
使用泛型时,也能限制泛型:
public class Demo2 {
public static void main(String[] args) {
// 需求:盘子里面只能放水果,泛型限制:
Plate<Fruit> fruitPlate = new Plate<>();
// 不能将一个装着苹果的盘子,看成一个装着水果的盘子
// 原因:多态是基于继承的,需要子父类的关系,
// 而泛型是类内部的属性,这句赋值依然还是盘子类!
// Plate<Fruit> p = new Plate<Apple>();
// 如果需要这样的逻辑,就应该使用通配符:
Plate<? extends Fruit> p2 = new Plate<Apple>();
// 除了限制类上界,另外也能限制下界:
Plate<? super Apple> p3 = new Plate<Fruit>();
// ? 可以当做Object看待,但实际?是替换,该是什么类型就是什么类型,确定了一个就不能用其他类型了:
// 实际上?就相当于? extends Object
Plate<?> p4 = new Plate<>();
// 泛型的原理实际上就是 编译完成后替换成对应的类,编译成源码时所有泛型都是替换掉了一个Object
// 所以泛型不能放基本数据类型,只能放对象:
// Number<int> p5 = new Number<>();
Number<Integer> p5 = new Number<>();
}
}
interface Fruit{}
class Apple implements Fruit{}
// 盘子类,使用 extends 限制泛型
class Plate<T extends Fruit>{
T[] data;
}
class Number<T>{
T[] data;
}
另外通配符联系List等数据结构也有一些限制,比如:
无法从 Arraylist<? extends T>
这样类型的 list对象中存数据add(),但可以取出、修改数据,并可以将一个list赋值给他;
无法从 Arraylist<? super T>
这样类型的 list对象中取出数据,但可以存数据,同样也可以再次赋值list;
这样设计的作用主要是为了安全的操作数组,保证某些情况下list的数据不会因为意外丢失,可以满足某些不允许删改数据的情况。
举例来说比如用来复制数组,详见java.util.Collections
的copy方法。
比较偏的知识点,不用太深究,不记得也没太大关系,大体上很少用到通配符。