泛型的使用,小编讲了不少了。前面有两篇 Java — 泛型 <T> 的使用介绍 之 泛型类 和 Java — 泛型 <T> 的使用介绍 之 泛型方法 可供翻阅。今天主要说下通配符的使用,其出现的意义在于修复泛型破坏的java类之间的继承,例如List < A> 和 List < B> ,类A是类B的父类,而List< A> 和 List< B> 则没有任何关系。如下代码:
@Test
public void test3() {
List<String> stringList = new ArrayList<>();
stringList.add("aaa");
stringList.add("ccc");
stringList.add("ddd");
List<Object> objectList = new ArrayList<>();
objectList.add(1223);
objectList.add("adcd");
objectList.add(1344);
//!!!下面的这两个操作都会编译报错!!!
//stringList = objectList;
//objectList = stringList;
}
那么,当出现一种需求,需要对List< A> 和 List< B> 进行通用操作,会怎么办呢?这里就出现了通配符 ? 下面,小编演示一下通配符是如何操作的。
一,通配符使用:
1,直接使用通配符
@Test
public void test3() {
//1,创建String list
List<String> stringList = new ArrayList<>();
stringList.add("aaa");
stringList.add("ccc");
stringList.add("ddd");
//2,创建Object list
List<Object> objectList = new ArrayList<>();
objectList.add(1223);
objectList.add("adcd");
objectList.add(1344);
//3,创建通配 list
List<?> list = new ArrayList<>();
//4,赋值操作成功
list = stringList;
//可以读取
list.get(0);
//但无法写入
//list.add("a"); //无法写入
System.out.println(list);
//5,赋值操作
list = objectList;
System.out.println(list);
}
输出:
D:\jdk\jdk1.8.0_171\bin\java.exe
[aaa, ccc, ddd]
[1223, adcd, 1344]
2,方法参数中使用通配符
@Test
public void test3() {
List<String> stringList = new ArrayList<>();
stringList.add("aaa");
stringList.add("ccc");
stringList.add("ddd");
show(stringList );
}
public void show(List<?> list) {
Iterator<?> iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
输出:
D:\jdk\jdk1.8.0_171\bin\java.exe
aaa
ccc
ddd
3,有限制条件的通配符的使用
@Test
public void test4() {
//1,创建 Son list,Son 代码下面会有。
List<Son> sonList = new ArrayList<>();
sonList.add(new Son("aa"));
sonList.add(new Son("bb"));
System.out.println(sonList);//[Son(skill=aa), Son(skill=bb)]
//2,创建Father list
List<Father> fatherList = new ArrayList<>();
fatherList.add(new Father("cc"));
fatherList.add(new Father("dd"));
System.out.println(fatherList);//[Father(name=cc), Father(name=dd)]
/**
* ? extends A: G<? extends A> 只能被A或者A的子类组成的G类型类赋值
* ? super A: G<? super A> 只能被A或者A的父类组成的G类型赋值
*/
List<? extends Father> list = new ArrayList<>();
List<? super Son> list2 = new ArrayList<>();
//赋值成功
list = sonList;
System.out.println(list); //[Son(skill=aa), Son(skill=bb)]
//赋值成功
list = fatherList;
System.out.println(fatherList);//[Father(name=cc), Father(name=dd)]
//赋值失败
List<Object> objectList = new ArrayList<>();
objectList.add("aa");
//list = objectList; //编译不通过
//赋值成功
list2 = objectList;
//赋值成功
list2 = sonList;
//赋值成功
list2 = fatherList;
//赋值失败
List<Grandson> grandsonList = new ArrayList<>();
grandsonList.add(new Grandson("sonar"));
grandsonList.add(new Grandson("high"));
//list2 = grandsonList; //编译不通过
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class Father{
private String name;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class Son extends Father{
private String skill;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class Grandson extends Son{
private String edu;
}