一 泛型方法的应用
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>,如果既要获取又要添加则不使用通配符。
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处代码的注释去掉,就会提示编译出错。