J2SE1.5便于开发的新语言特性:Joshua Bloch的访谈录(3)

类别:Java 点击:0 评论:0 推荐:

您能把泛型和"for增强"结合在一起吗?

 

当然没问题。你看,我们把泛型技术融入到上面的代码中:

 

void cancelAll(Collection<TimerTask> c) {

    for (TimerTask task : c)

        task.cancel();

}

 

我觉得这是更优雅的代码。现在代码可以准确地表明他要做什么,而且提供了编译期类型安全的保证。

 

请给我们讲讲自动置入(autoboxing)。

 

大家都知道,Java语言有两种类型的变量:一种是基本类型,一种是对象的索引类型(object references)。基本类型的变量不能置入到集合中,所以如果你想把基本变量存入集合或从集合中取出的话,你不得不在基本类型(如int)和对应的包装类(如Integer)之间转来转去。每个这样做的人都会觉得这不是好的做法。

比如,我们考虑一个程序它用来统计输入命令行中的词的频率。我们使用一个Map,它的关键字是输入的词,值是这个词在命令行中出现的次数:

 

public class Freq {

    private static final Integer ONE = new Integer(1);

 

    public static void main(String args[]) {

        // Maps word (String) to frequency (Integer)

        Map m = new TreeMap();

 

        for (int i=0; i<args.length; i++) {

            Integer freq = (Integer) m.get(args[i]);

            m.put(args[i], (freq==null ? ONE :

                  new Integer(freq.intValue() + 1)));

        }

        System.out.println(m);

    }

}

 

你看看在循环中增加数量的代码是多么地混乱?现在我们用autoboxing、泛型和"for增强"来重写一下这个程序:

 

public class Freq {

    public static void main(String args[]) {

       Map<String, Integer> m = new TreeMap<String, Integer>();

       for (String word : args)

           m.put(word, m.get(word) + 1);

       System.out.println(m);

    }

}

 

是不是好多了? 有一点值得注意:程序假设当你自动取出null的时候,你会得到0。是否是这种情况还是一个问题。另外一个可选择的就是抛出一个NullPointerException 异常。这两种选择都有其各自的优势。“自动取出null得到0”可以美化像上面这样的程序,但是它也可能隐蔽了真正的错误。如果谁有强烈的意见或者有能令人信服的关于这个问题更好的解决方案,请与JSR-201专家组联系。

本文地址:http://com.8s8s.com/it/it17841.htm