generic type的定义:就是在类型上参数化的泛型类或者接口
定义generic type 的模板(generic 类和接口都是这么定义的)
class name<T1, T2, ..., Tn> { /* ... */ }例子:
/** * Generic version of the Box class. * @param <T> the type of the value being boxed */ public class Box<T> { // T stands for "Type" private T t; public void set(T t) { this.t = t; } public T get() { return t; } } public interface Pair<K, V> { public K getKey(); public V getValue(); } //多个 type parameter public class OrderedPair<K, V> implements Pair<K, V> { private K key; private V value; public OrderedPair(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public V getValue() { return value; } }继承(inheritance),implement
继承或者实现的原则:
就是泛型父类或者接口的type parameter 在子类泛型中要保留下来,自己可以新增额外的type parameter对于Parameterized type,只有相同type argument的的Parameterized type 父类和子类之间才存在subtype(父子的关系),如果不是相同的Parameterized type不同,则不存在subtype关系例子
Box<Number> 跟 BOX<Integer>不存在父子关系 interface PayloadList<E,P> extends List<E> { void setPayload(int index, P val); ... }type parameter
命名方式
E - Element (used extensively by the Java Collections Framework)K - KeyN - NumberT - TypeV - ValueS,U,V etc. - 2nd, 3rd, 4th types概念的区别
public class Box<T> {} Box<String> box; T为type parameter String 为 type argument BOX<T> generic type Box<String> Parameterized type什么是 Bouded Type Parameters
就是如果是Box的时候,T可以为任何类型,包括 Parameterized Type 类型,但如果我们想要该Box geneirc type 只能 parameterized 为某一指定范围的类型,那么则需要使用Bounded Type Parameter 来完成这个需求
有什么用
一:就是规范Parameterized Type的范围,这可以让我们针对这些类型进行某些特定的操作
二:在实现泛型算法的时候,需要用到该功能
如何定义
Class A { /* ... */ } interface B { /* ... */ } interface C { /* ... */ } class D <T extends A & B & C> { /* ... */ }例子:
public class Box<T> { private T t; public void set(T t) { this.t = t; } public T get() { return t; } public <U extends Number> void inspect(U u){ System.out.println("T: " + t.getClass().getName()); System.out.println("U: " + u.getClass().getName()); } public static void main(String[] args) { Box<Integer> integerBox = new Box<Integer>(); integerBox.set(new Integer(10)); integerBox.inspect("some text"); // error: this is still String! } }如何定义Generic Method
public class Util { //定义 public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) { return p1.getKey().equals(p2.getKey()) && p1.getValue().equals(p2.getValue()); } } public class Pair<K, V> { private K key; private V value; public Pair(K key, V value) { this.key = key; this.value = value; } public void setKey(K key) { this.key = key; } public void setValue(V value) { this.value = value; } public K getKey() { return key; } public V getValue() { return value; } } //使用 Pair<Integer, String> p1 = new Pair<>(1, "apple"); Pair<Integer, String> p2 = new Pair<>(2, "pear"); boolean same = Util.<Integer, String>compare(p1, p2); //也可以不同指定方法的type argument,因为其会compile会自动推断出其类型 Pair<Integer, String> p1 = new Pair<>(1, "apple"); Pair<Integer, String> p2 = new Pair<>(2, "pear"); boolean same = Util.compare(p1, p2);跟上面讲的概念差不多
例子
public static <T> int countGreaterThan(T[] anArray, T elem) { int count = 0; for (T e : anArray) if (e > elem) // compiler error ++count; return count; } //改进 public static <T extends Comparable<T>> int countGreaterThan(T[] anArray, T elem) { int count = 0; for (T e : anArray) if (e.compareTo(elem) > 0) ++count; return count; } public static <T extends Comparable<T>> int countGreaterThan(T[] anArray, T elem) { int count = 0; for (T e : anArray) if (e.compareTo(elem) > 0) ++count; return count; }what:
就是之前有讲过,List 和List,List之间不存在subtype,那如果想要List,List共同的Paramter type 的父类,如果做到 ,那则需WildCards,来创建该Paramterized type 父类,
why
可以在static method中实现通用算法
如何使用Wild
//List<? extends Number>是已经参数化(parameterd)的类,其是List<Integer>,List<Double>共同的父类,这样就可以通过该父类来动态操作List中一些通用功能,例如遍历 public static double sumOfList(List<? extends Number> list) { double s = 0.0; for (Number n : list) s += n.doubleValue(); return s; } List<Integer> li = Arrays.asList(1, 2, 3); System.out.println("sum = " + sumOfList(li)); List<Double> ld = Arrays.asList(1.2, 2.3, 3.5); System.out.println("sum = " + sumOfList(ld)); class NaturalNumber { private int i; public NaturalNumber(int i) { this.i = i; } // ... } class EvenNumber extends NaturalNumber { public EvenNumber(int i) { super(i); } // ... } //注意:不是在List中所有的通用方法都可以被调用,一旦涉及到具体类型的操作,则不可以,否则出现编译错误 List<EvenNumber> le = new ArrayList<>(); List<? extends NaturalNumber> ln = le; ln.add(new NaturalNumber(35)); // compile-time error //原则: You can add null. You can invoke clear. You can get the iterator and invoke remove. You can capture the wildcard and write elements that you've read from the list. //总结 就是如果某些操作是涉及到特定类型的时候,则不能使用该操作,例如add(),所以只能去添加null clear()操作是所有的List类型都是可以的,所以可以进行更多具体的内容,请查看官方文档
