第一章深入Java泛型
二、通配符与嵌套
2.1 通配符
?:表示类型不确定,只能用于声明变量或者形参上,不能用在创建泛型类、泛型方法和接口上。
public static void main(String[] args) {
List<?> list = new ArrayList<Integer>();
list = new ArrayList<String>();
test(list);
}
public static void test(List<?> list) {}
? 号通配符表示可以匹配任意类型,任意的 Java 类都可以匹配。
在使用 ? 号通配符的时候:只能调用对象与类型无关的方法,不能调用对象与类型有关的方法。
2.2 泛型嵌套
定义两个泛型类,Myclass 类的泛型就是 student 类,而 student 类的发逆行是 String 类。
class Student<T> {
private T score;
public T getScore() {
return score;
}
public void setScore(T score) {
this.score = score;
}
}
class MyClass<T> {
private T cls;
public T getCls() {
return cls;
}
public void setCls(T cls) {
this.cls = cls;
}
}
public static void main(String[] args) {
Student<String> stu = new String<String>();
stu.setScore("great");
// 嵌套泛型
MyClass<Student<String>> cls = new MyClass<Student<String>>();
cls.setCls(stu);
Student<String> stu2 = new Student<String>();
stu2 = cls.getCls();
System.out.println(stu2.getScore());// great
}
如上就实现了泛型的嵌套,在 HashMap 中对键值对进行遍历的时候,也利用了泛型的嵌套。
public static void main(String[] args) {
Map<String, String> map = new HashMap<>(String, String);
map.put("a", "java300");
map.put("b", "马士兵javase");
Set<Entry<String, String>> entrySet = map.entrySet();
for(Entry<String, String> entry: entrySet) {
String key = entry.getKey();
String value = entry.getValue();
}
}
2.3 通配符和泛型方法
大多时候,我们都可以使用泛型方法来代替通配符的。
// 使用通配符
public static void test(List<?> list) {}
// 使用泛型方法
public <T> void test2(List<T> t)
上面这两个方法都是可以的,那么问题来了,我们使用通配符还是使用泛型方法呢?
原则:
- 如果参数之间的类型有依赖关系,或者返回值是与参数之间有依赖关系的,就使用泛型方法
- 如果没有依赖关系的,使用通配符,通配符会更灵活一些