一 泛型方法的应用
1 代码示例
import java.util.Vector;
public class RandomGenerObject {
/**
* @param args
*/
public static void main(String[] args) {
Vector<Integer> v = new Vector<Integer>();
Vector<Object> v1 = new Vector<Object>();
//radomMeth(v); //a处代码
radomMeth(v1);
}
public static void radomMeth(Vector<Object> vector) {
vector.add("cjg"); //b处代码
vector.add(156); //c处代码
for (Object obj : vector) {
System.out.println(obj);
}
}
}
2 运行结果
cjg
156
3 代码解析
- 在radomMeth()方法中,对于Vector<Object>泛型,实现了可以向该参数中添加任意类型的对象,例如b处代码和c处代码,这是因为任何对象的基类都是Object类型,所以任何类型的对象都可以自动转换成Object类型。
- 在具体调用radomMeth()方法时,只要传入的参数为Object类型泛型对象,才会正确运行。如果是其他类型的泛型对象,则会编译出错。这是因为参数化类型无继承性特性。如果把a处代码的注释去掉,就会提示编译出错。
二 泛型通配符的应用
1 代码示例
import java.util.Vector;
public class RandomGener {
/**
* @param args
*/
public static void main(String[] args) {
Vector<Integer> v = new Vector<Integer>();
v.add(1);
v.add(2);
radomMeth(v);
Vector<Object> v1 = new Vector<Object>();
v1.add("aa");
v1.add(2.2);
radomMeth(v1);
}
public static void radomMeth(Vector<?> vector) {
// vector.add("1"); //a处代码
System.out.println("输出" + vector + "各个成员----------");
for (Object obj : vector) {
System.out.println(obj);
}
System.out.println("对象的大小" + vector.size());
}
}
2 运行结果
输出[1, 2]各个成员----------
1
2
对象的大小2
输出[aa, 2.2]各个成员----------
aa
2.2
对象的大小2
3 代码解析
- 在radomMeth()方法中,通过“?”标识实现接受任何类型参数的方法,即在具体调用该方法时,传入的对象可以是任意类型,例如Integer类型的对象v和Object类型的对象v1。
- 在radomMeth()方法中,虽然可以接受任意类型的参数,但是具体接受什么类型只有在具体调用方法时才能确定。因此在调用a处代码时,会编译报错。可是如果调用与参数类型无关的方法size(),则不会编译报错。
三 通配符的上限和下限的应用
1 代码示例
import java.util.ArrayList;
import java.util.List;
public class IntegrationGener {
public static void main(String[] args) {
List<Number> listNums = new ArrayList<Number>();
listNums.add(1);
listNums.add(1.23);
List<Integer> listInteger = new ArrayList<Integer>();
List<? extends Number> listNums2 = listInteger;
List<? super Integer> listNums3 = listInteger;
listNums3.add(7);
listNums3.add(null);
System.out.println("listNums3中的元素" + listNums3.get(0));
System.out.println("listNums3中的元素个数" + listNums3.size());
System.out.println("listNums2中的元素" + listNums2.get(0));
System.out.println("listNums2中的元素个数" + listNums2.size());
listNums3.add(null);
System.out.println("listNums3中的元素个数" + listNums3.size());
System.out.println("listNums2中的元素个数" + listNums2.size());
List<Number> listNums1 = new ArrayList<Number>();
List<? super Integer> listNums4 = listNums1;
listNums4.add(6);
}
}
2 运行结果
listNums3中的元素7
listNums3中的元素个数2
listNums2中的元素7
listNums2中的元素个数2
listNums3中的元素个数3
listNums2中的元素个数3
3 代码解析
- 为了解决泛型参数类型无继承性,出现了extends和super标识符号。List<? extends Number> listNums2表示listNums2对象可以被Number类型的任何子类型对象(List<Integer> listInteger)赋值。List<? super Integer> listNums3表示listNums3对象可以被Integer类型的任何父类(listNums1)或Interger类型对象(listInteger)赋值。
- 一条比较通用的原则是,如果要向列表中添加元素则用<? super T>,如果要从列表中获取元素则用<? extends T>,如果既要获取又要添加则不使用通配符。