像一个函数能接受参数一样,一个泛型也能接受参数.这就是一个泛型经常被称为一个参数化类型的原因.但是不像函数用()传递参数,泛型是用<>传递参数的.声明一个泛型和声明一个普通类没有什么区别,只不过你把泛型的变量放在<>中. 比如,在JDK 5中,你可以这样声明一个java.util.List : List myList; E 称为类型变量.意味着一个变量将被一个类型替代.替代类型变量的值将被当作参数或返回类型.对于List接口来说,当一个实例被创建以后,E 将被当作一个add或别的函数的参数.E 也会使get或别的参数的返回值.下面是add和get的定义:
-----------------------------译者添加-------------------- List numberList= new ArrayList(); numberList.add(2.0); numberList.add(2); -----------------------------译者添加--------------------
public class GenericListTest { public static void main(String[] args) { // in JDK 1.4 List stringList1 = new ArrayList(); stringList1.add("Java 1.0 - 5.0"); stringList1.add("without generics"); // cast to java.lang.String String s1 = (String) stringList1.get(0); System.out.println(s1.toUpperCase());
// now with generics in JDK 5 List stringList2 = new ArrayList(); stringList2.add("Java 5.0"); stringList2.add("with generics"); // no need for type casting String s2 = stringList2.get(0); System.out.println(s2.toUpperCase()); } }
package com.brainysoftware.jdk5.app16; import java.util.ArrayList; import java.util.List; public class ListOfListsTest { public static void main(String[] args) { List listOfStrings = new ArrayList(); listOfStrings.add("Hello again"); List> listOfLists = new ArrayList>(); listOfLists.add(listOfStrings); String s = listOfLists.get(0).get(0); System.out.println(s); // prints "Hello again" } }
public class AllowedTypeTest { public static void doIt(List l) { } public static void main(String[] args) { List myList = new ArrayList(); // 这里将产生一个错误 doIt(myList); } }
public static void printList(List<?> list) { for (Object element : list) { System.out.println(element); } } public static void main(String[] args) { List list1 = new ArrayList(); list1.add("Hello"); list1.add("World"); printList(list1);
List list2 = new ArrayList(); list2.add(100); list2.add(200); printList(list2); } }
package com.brainysoftware.jdk5.app16; import java.util.ArrayList; import java.util.List; public class BoundedWildcardTest { public static double getAverage(List<? extends Number> numberList) { double total = 0.0; for (Number number : numberList) total += number.doubleValue(); return total/numberList.size(); }
public static void main(String[] args) { List integerList = new ArrayList(); integerList.add(3); integerList.add(30); integerList.add(300); System.out.println(getAverage(integerList)); // 111.0 List doubleList = new ArrayList(); doubleList.add(3.0); doubleList.add(33.0); System.out.println(getAverage(doubleList)); // 18.0 } }
下界规则 关键字extends定义了一个类型变量的上界。通过使用super关键字,我们可以定义一个类型变量的下界,尽管使用的情况不多。比如,如果一个函数的参数是List<? super Integer>,那么意味着你可以传递一个List的实例或者任何java.lang.Integer的超类(superclass)。
package com.brainysoftware.jdk5.app16; public class Point { T x; T y; public Point(T x, T y) { this.x = x; this.y = y; } public T getX() { return x; } public T getY() { return y; } public void setX(T x) { this.x = x; } public void setY(T y) { this.y = y; } }