Chinaunix首页 | 论坛 | 博客
  • 博客访问: 522133
  • 博文数量: 147
  • 博客积分: 10105
  • 博客等级: 上将
  • 技术积分: 1594
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-14 10:18
文章分类

全部博文(147)

文章存档

2011年(4)

2010年(4)

2009年(6)

2008年(5)

2007年(40)

2006年(88)

我的朋友

分类: Java

2006-11-16 10:39:28

更深入了解泛型(是JDK5.0的特性)
public class C {
 public String getString(T obj) { //实现了一个泛型方法jre要是5.0
        return obj.toString();
 }
 public static void main(String [] args){
        C t = new C();
        String s = "Hello";
        Integer i = 100;
        System.out.println(t.getString(s));
        System.out.println(t.getString(i));
        }
}
Hello
100

(1)层层推进的泛型声明

  “List list;”表示什么呢?就是只接收List型的参数,比如:

        List list = new ArrayList();
        list.add(new ArrayList());
        list.add(new Vector());
        list.add(new LinkedList());

  这里要注意List是接口,ArrayList、Vector、LinkedList都是这一接口下的实现类。下面这个有点怪异了,“List> list;”表示它只接受List型的参数,而且这种List型的参数又是只是只接受String型,有点层层推进的味道在里面了。

        List> list = new ArrayList>();
        list.add(new ArrayList());
        list.add(new Vector());
        list.add(new LinkedList());

(2)使用泛型上限通通配符:extends

  这里要着重强调一点:变量的泛型声明和方法的参数的泛型声明有很大差别。

  变量声明成某类型,同时也可以接受它的子类。比如说Integer、Long、Float都是抽象类Number的子类,所以下面的代码一点问题也没有:

        List list = new ArrayList();
        list.add(new Integer(1));
        list.add(new Long(1));
        list.add(new Float(1.2));

  但如果换成方法参数的泛型声明则要严格得多了:子类也是不行的。比如下面的代码就是错误的,因为printList参数只接受Number值的List,就是是Number子类的Integer值的List也不行。

    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(new Integer(1));
        list.add(new Integer(2));
        printList(list);
    }
   
    private static void printList(List list){
        for (Number num : list) {
            System.out.println(num);
        }
    }

 上面代码修改的方法有两个,如下

修改方法一:改变量的泛型声明
  将 List list = new ArrayList();
  改为 List list = new ArrayList();

修改方法二:用界限通配符改方法参数的泛型声明
  将 printList(List list)
  改为 printList(List list)
  说明:extends 的含义就是表示参数可以接受Number型的子类。

(3)使用泛型下限通通配符:super

    在上限就有下限,下限行就是super,用法和extends一样,含义则和extends相反。比如printList(List list)表示参数可以接受Integer型及Integer型的超类,即Number了,当然也包括Object这个顶级类。

(4)配置符:?

  ?表示可以接受任何类型,不过我觉得它用得不多,因为printList(List list)和printList(List list)的作用是一样的。

五、创建一个支持泛型的类

(1)创建一个泛型的类

public class Point {
    T x;
    T 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;
    }
}

  使用这个类的代码如下:

        Point p = new Point();
        p.setX(new Integer(1));
        p.setY(new Integer(2));
       
        Point b = new Point();
        b.setX("1");
        b.setY("2");

  说明:在Point的定义中,T并非关键字,你也可以这样定义Point,当然一般还是写T吧,简单也规范。

(2)泛型类的继承与实现

  java.util.Comparator类是JDK里用来排序的,其源代码如下:

package java.util;
public interface Comparator {
    int compare(T o1, T o2);
    boolean equals(Object obj);
}

   一个实现此接口的类如下:

    public class MyComparator implements Comparator {
        public int compare(ObjectInstance o1, ObjectInstance o2) {
            String s1 = o1.getObjectName().getCanonicalName();
            String s2 = o2.getObjectName().getCanonicalName();
            return s1.compareToIgnoreCase(s2);
        }
    }

  说明:ObjectInstance可能大家还太明白,这是我实际项目中的一段代码(关于JMX的),ObjectInstance全称javax.management.ObjectInstance。MyComparator的使用代码如下:

Set set = ......(省略)
List mbeans = new ArrayList(set);
Collections.sort(mbeans, new MyComparator());

六、最后的感言

  JAVA有了泛型就象老光棍讨了老婆,好处大大的,但和女人一样麻烦也跟着来了:它的严格类型检查,使隐藏的BUG更少。有些地方确实也使代码简洁了,有些地方却会使得代码更复杂。所以运用之妙在于是否用得适当,尽量把泛型往简单里用,别越搞越复杂了。 

阅读(649) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~