part 1: 工作
具体内容:山信线下结算担保费
进度:已完成
part 2:学习内容
1.泛型
1.1 泛型就是编写模板代码来适应任意类型,例如ArrayList<T>
,然后在代码中为用到的类创建对应的ArrayList<类型>
public class ArrayList<T> {
private T[] array;
private int size;
public void add(T e) {...}
public void remove(int index) {...}
public T get(int index) {...}
}
// 创建可以存储String的ArrayList:
ArrayList<String> strList = new ArrayList<String>();
// 创建可以存储Float的ArrayList:
ArrayList<Float> floatList = new ArrayList<Float>();
// 创建可以存储Person的ArrayList:
ArrayList<Person> personList = new ArrayList<Person>();
写一个模板可以创建任意类型的ArrayList
:
1.2 使用时不必对类型进行强制转换,它通过编译器对类型进行检查
1.3 泛型的继承关系:可以把ArrayList<Integer>
向上转型为List<Integer>
(T
不能变!),但不能把ArrayList<Integer>
向上转型为ArrayList<Number>
(T
不能变成父类)
1.4 泛型实现方式是擦拭法
什么是擦拭法:擦拭法是泛型在运行的时候,不会暴露出真是类型,可以说是被拭去了。
Java的泛型是由编译器在编译时实行的,编译器内部永远把所有类型T
视为Object
处理,但是,在需要转型的时候,编译器会根据T
的类型自动为我们实行安全地强制转型。
擦拭法决定了泛型<T>
:
- 不能是基本类型,例如:
int
; - 不能获取带泛型类型的
Class
,例如:Pair<String>.class
; - 不能判断带泛型类型的类型,例如:
x instanceof Pair<String>
; - 不能实例化
T
类型,例如:new T()
。
2.1 extends通配符
public class Main { public static void main(String[] args) { Pair<Integer> p = new Pair<>(123, 456); int n = add(p); System.out.println(n); } static int add(Pair<Number> p) { Number first = p.getFirst(); Number last = p.getLast(); return first.intValue() + last.intValue(); } } class Pair<T> { private T first; private T last; public Pair(T first, T last) { this.first = first; this.last = last; } public T getFirst() { return first; } public T getLast() { return last; } }
当传入的参数是Integer 123和456时,会得到编译错误,因为 Pair<Integer>
不是Pair<Number>
的子类,因此,add(Pair<Number>)
不接受参数类型Pair<Integer>
。
此时,使用Pair<? extends Number>
使得方法接收所有泛型类型为Number
或Number
子类的Pair
类型,使得方法参数接受Pair<Integer>。
static int add(Pair<? extends Number> p) {
Number first = p.getFirst();
Number last = p.getLast();
return first.intValue() + last.intValue();
}
2.2 使用类似<? extends Number>
通配符作为方法参数时表示:
-
方法内部可以调用获取
Number
引用的方法,例如:Number n = obj.getFirst();
; -
方法内部无法调用传入
Number
引用的方法(null
除外),例如:obj.setFirst(Number n);
即使用extends
通配符表示可以读,不能写。
2.3在定义泛型类型Pair<T>
的时候,也可以使用extends
通配符来限定T
的类型:
public class Pair<T extends Number> { ... }
Pair<Number> p1 = null;
Pair<Integer> p2 = new Pair<>(1, 2);
Pair<Double> p3 = null;
Pair<String> p1 = null; // compile error!
Pair<Object> p2 = null; // compile error!
为Number
、Integer
和Double
都符合<T extends Number>
。
非Number
类型将无法通过编译: