public class GenericClassDemo {
public static void main(String[] args) {
List integerList = new ArrayList<>();
print(integerList);
}
public static void print(List list) {
// 打印...
}
}
public static void main(String[] args) {
List integerList = new ArrayList<>();
integerList.add(1);
List longList = new ArrayList<>();
longList.add(1L);
List extends Number> numberList = new ArrayList<>();
numberList = 随机指向integerList或longList等子类型List;
numberList.add(1); // 由于无法确定numberList指向哪个List,所以干脆禁止add(万一指向integerList,那么add(1L)就不合适了,取出时可能转型错误)
}
还不是很明白?那就再举个例子:
但是对于取出,extends可不含糊:
public static void main(String[] args) {
List integerList = new ArrayList<>();
integerList.add(1);
List longList = new ArrayList<>();
longList.add(1L);
List extends Number> numberList = integerList; // 不管numberList指向integerList还是longList
Number number = numberList.get(0); // 取出来的元素都可以转Number,因为Long/Integer都是它子类
}
super是下边界通配符,所以对于List super Integer>,元素类型的地板就是Integer,右边List的元素类型只能比Integer“高”。换句话说,List super Integer>只能指向List、List等父类型List。
记忆方法: List super Integer> list = ...,把?看做右边List的元素(暂不确定,用?代替),? super Integer表示右边元素必须是Integer的父类。
super的特点是:
List super Integer>指向:只能指向父类型List,比如List、List
List super Integer>存入:只能存Integer及其子类型元素
List super Integer>取出:只能转Object
至此,我们发现Java同时满足了:
extends:指向子类型List
简单泛型T:指向同类型List
super:指向父类型List
说完指向问题,我们再来探讨一下存取问题。思路还是一样,既然Java允许List super Integer>指向List等父类型,那么如何防止存取出错呢?
假设存在class Human implement Swimming, Speaking,那么Swimming和Speaking都是Human的父类/父接口。由于List super Human>可以指向父类型List,要么指向SwimmingList,要么指向SpeakingList。
public static void main(String[] args) {
List swimmingList = new ArrayList<>();
// 假设加入了很多实现了Swimming接口的元素,比如Dolphin(海豚)
// swimmingList.add(dolphin)...
List speakingList = new ArrayList<>();
// 假设加入了很多实现了Speaking接口的元素,比如Parrot(鹦鹉)
// speakingList.add(parrot)...
List super Human> humanList = swimmingList / speakingList; // 指向随机的List
humanList.add(...) // 是否应该允许存入 Parrot(鹦鹉)?
}
此时对于List super Human>,是否应该允许加入 Parrot(鹦鹉)呢?答案是最好不要。因为humanList的指向是不确定的,如果刚好指向的是swimmingList,那么list.add(parrot)显然是不合适的。
只有存入Human及其子类才是安全的:
介绍完super的存入,最后聊聊super的取出。由于List super Human>可以指向任意Human父类型的List,可能是SwimmingList,也可能是SpeakingList。这意味取出的元素可能是Swimming,也可能是Speaking,是不确定的,所以用Swimming或Speaking都不太合适。
lua:
local access_token = ngx.var.cookie_SGAccessToken
if access_token then
ngx.header["Set-Cookie"] = "SGAccessToken="..access_token.."; path=/;Max-Age=3000"
end