疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java泛型探索—小特性


 

 
泛型特性(小篇幅)
 
1. 补充介绍一些常见的泛型特性:
 
    类型参数T可以是recursive(类似递归性),它的边界可以是类型参数是自身的接口或类。
 
如我实现寻找最大值的方法,可以这么写:
 
复制代码
public static <T extends Comparable<T>> T max(Collection<T> coll) {
    T candidate = coll.iterator().next();
    for (T elt : coll) {
        if(candidate.compareTo(elt) < 0)
            candidate = elt;
    }
    return candidate;
}
复制代码
    泛型多边界(Multiple Bounds)
 
复制代码
    public static<S extends Readable & Closeable, T extends Appendable & Closeable> 
    void copy(S src ,T trg, int size) throws IOException {
        try {
         CharBuffer buf = CharBuffer.allocate(size);
         int i = src.read(buf);
         while (i >= 0) {
             buf.flip();
             trg.append(buf);
             buf.clear();
             i = src.read(buf);
         }
        } finally {
            src.close();
            trg.close();
        }
    }
复制代码
 
 
2. Bridges特性
 
对于泛型接口而言,如Comparable<T>,在编译时会插入额外的方法,这些方法被叫做bridges。
 
在没有泛型以前,Comparable接口是怎么实现的呢? 我们省略一些代码,简写一下,代码如下:
 
复制代码
interface Comparable {
    public int compareTo(T o); }
class Integer implements Comparable { 
    private final int value;
    public Integer(int value) { 
        this.value = value; 
    } 
    public int compareTo(Integer i) {
        return (value < i.value) ? -1 : (value == i.value) ? 0 : 1; 
    }
 
    public int compareTo(Object o) {
        return this.compareTo((Integer)o);
    }
}
复制代码
我们将 compareTo(Object o)方法称为bridge。
 
泛型接口在jvm编译过程中,就会产生bridge方法,我们就以Comparable<T>为例:
 
复制代码
interface Comparable<T> {
    public int compareTo(T o); }
class Integer implements Comparable<Integer> { 
    private final int value;
    public Integer(int value) { 
        this.value = value; 
    } 
    public int compareTo(Integer i) {
        return (value < i.value) ? -1 : (value == i.value) ? 0 : 1; 
    }
}
复制代码
我们以Integer为例,它实现了Comparable接口,我们通过反射查看有几个compareTo方法,see:
 
for (Method m : Integer.class.getMethods()) {
     if (m.getName().equals("compareTo"))
     System.out.println(m.toGenericString());
}
它的输出结果是这样的:
 
public int java.lang.Integer.compareTo(java.lang.Integer)
public int java.lang.Integer.compareTo(java.lang.Object)
可以看出确实是这样的。至于为什么会这样,接下来慢慢介绍,先留个坑,我们可以先看看bridge方法有什么用处。
 
 
 
3. Covariant Overriding (协变覆盖)
 
 在java1.4的时候,方法的覆盖必须严格意义上的参数类型和返回类型相同,而java1.5以后,方法的覆盖,只需要参数列表相同,而参数列表是一样的,如果返回类型
 
是父类的子类,那这个子类的方法也可以overriding父类的方法。
 
  我们以clone方法为例,在Object类中:
 
class Object {
    ...
    public Object clone() { ... }
}
而在Point类中:
 
复制代码
class Point extends Object {
    public int x;
    public int y;
    public Point(int x,int y) {
        this.x = x;
        this.y = y;
    }
    public Point clone() {
        return new Point(x,y);
    }
}
复制代码
在java1.4之前,上面的clone方法无法覆盖Object的clone方法,但从java1.5开始就可以这么写,这是为什么呢,还是bridge的功劳:
 
我们在利用反射看看,Point类中有几个clone方方法:
 
for(Method m : Point.class.getMethods()) {
   if(m.getName().equals("clone"))
System.out.println(m.toGenericString());
}
输出如下:
output
public Point Point.clone()
public java.lang.Object Point.clone() throws java.lang.CloneNotSupportedException
java.lang.Object Point.clone()方法只是简单的调用了Point.clone()方法,就这样实现了覆盖。
 
好了,这些是泛型的零散知识点,先介绍一下,后面继续todo。