package com.imooc.config;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class Testss {
@Test
public void main1() {
//无边界的通配符的使用方法
//有一点我们必须明确, 我们不能对List<?>使用add方法,
// 仅有一个例外, 就是add(null). 为什么呢? 因为我们不确定该List的类型,
// 不知道add什么类型的数据才对, 只有null是所有引用数据类型都具有的元素
List<String> l1 = new ArrayList<>();
l1.add("aa");
l1.add("bb");
l1.add("cc");
List<?> list = l1;
for(Object object: list){
System.out.println(object);
}
// list.add(o); // 编译报错
// list.add(1); // 编译报错
// list.add("ABC"); // 编译报错
list.add(null);
// List<?>也不能使用get方法, 只有Object类型是个例外. 原因也很简单, 因为我们不知道传入的List是什么泛型的,
// 所以无法接受得到的get, 但是Object是所有数据类型的父类, 所以只有接受他可以, 请看下面代码:
// String str = list.get(0);// 编译报错
Object str = list.get(0);
String str2 =(String)list.get(0);//当然我们可以用强制类型转换的方式,前提是再确定类型的情况下,但这样一来?就没有意义了
}
@Test
public void main2() {
//固定上边界的通配符的使用, 我仍旧以List为例来说明:
List<Integer> l1 = new ArrayList<>();
l1.add(11);
l1.add(22);
l1.add(33);
List<? extends Number > list = l1;
for(Number number : list){
System.out.println(number);
}
//有一点我们需要记住的是, List<? extends E>不能使用add方法,
//原因很简单, 泛型<? extends E>指的是E及其子类, 这里传入的可能是Integer,
// 也可能是Double, 我们在写这个方法时不能确定传入的什么类型的数据
//但是get的时候是可以得到一个Number, 也就是上边界类型的数据的
Number number = list.get(0);
}
@Test
public void main3() {
//固定下边界的通配符的使用, 我仍旧以List为例来说明:
List<Object> list1 = new ArrayList<>();
addNumbers(list1);
System.out.println(list1);
List<Number> list2 = new ArrayList<>();
addNumbers(list2);
System.out.println(list2);
List<Double> list3 = new ArrayList<>();
//addNumbers(list3); // 编译报错
//我们看到, List<? super E>是能够调用add方法的, 因为我们在addNumbers所add的元素就是Integer类型的,
// 而传入的list不管是什么, 都一定是Integer或其父类泛型的List, 这时add一个Integer元素是没有任何疑问的.
// 但是, 我们不能使用get方法
//这个原因也是很简单的, 因为我们所传入的类都是Integer的类或其父类,
// 所传入的数据类型可能是Integer到Object之间的任何类型, 这是无法预料的,
// 也就无法接收. 唯一能确定的就是Object, 因为所有类型都是其子类型
}
public static void addNumbers(List<? super Integer> list) {
for (int i = 1; i <= 10; i++) {
list.add(i);
}
}
}