小议局部类(2)

2008-05-24 05:34:25.0     浏览:181     来源:天新网
关键词:

小议局部类(2)

让我们来看看另一个例子,更深层的比较匿名类和局部类:


import Java.util.*;


public class LocalDemo2 {


// 使用两个单独的匿名类实例对两个列表进行排序


static void sort1(List list1, List list2) {


Collections.sort(list1, new Comparator() {


public int compare(


Object o1, Object o2) {


int cc = ((Integer)o1).compareTo(o2);


return (cc < 0 ? 1 : cc > 0 ? -1 : 0);


}


});


Collections.sort(list2, new Comparator() {


public int compare(


Object o1, Object o2) {


int cc = ((Integer)o1).compareTo(o2);

return (cc < 0 ? 1 : cc > 0 ? -1 : 0);


}


});


}


// 使用一个局部类的两个实例来对两个列表进行排序


static void sort2(List list1, List list2) {


class MyComparator implements Comparator {


public int compare(


Object o1, Object o2) {


int cc = ((Integer)o1).compareTo(o2);


return (cc < 0 ? 1 : cc > 0 ? -1 : 0);


}


}


Collections.sort(list1, new MyComparator());


Collections.sort(list2, new MyComparator());


}


// 使用一个匿名类的一个实例来对两个列表进行排序


static void sort3(List list1, List list2) {


Comparator cmp = new Comparator() {


public int compare(


Object o1, Object o2) {


int cc = ((Integer)o1).compareTo(o2);


return (cc < 0 ? 1 : cc > 0 ? -1 : 0);


}


};


Collections.sort(list1, cmp);


Collections.sort(list2, cmp);


}


// 使用一个局部类的一个实例来对两个列表进行排序


static void sort4(List list1, List list2) {


class MyComparator implements Comparator {


public int compare(


Object o1, Object o2) {


int cc = ((Integer)o1).compareTo(o2);


return (cc < 0 ? 1 : cc > 0 ? -1 : 0);


}


}


Comparator cmp = new MyComparator();



Collections.sort(list1, cmp);


Collections.sort(list2, cmp);


}


static class AppComparator implements


Comparator {


public int compare(Object o1, Object o2) {

int cc = ((Integer)o1).compareTo(o2);


return (cc < 0 ? 1 : cc > 0 ? -1 : 0);


}


}


static Comparator appcomparator =


new AppComparator();



// 使用应用程序中定义的比较器来对两个列表进行排序


static void sort5(List list1, List list2) {


Collections.sort(list1, appcomparator);


Collections.sort(list2, appcomparator);


}


public static void main(String[] args) {


List list1 = new ArrayList();


list1.add(new Integer(1));


list1.add(new Integer(2));


list1.add(new Integer(3));


List list2 = new ArrayList();


list2.add(new Integer(4));


list2.add(new Integer(5));


list2.add(new Integer(6));


//sort1(list1, list2);


//sort2(list1, list2);

//sort3(list1, list2);


//sort4(list1, list2);


sort5(list1, list2);


System.out.println(list1);


System.out.println(list2);


}


}


输出结果是:


[3, 2, 1]


[6, 5, 4]


程序中所有这些排序的方法都做同样的事情??降序排序两个列表中的 Integer 对象。


sort1 使用两个匿名类,每个都实现了 Comparator 接口。这两个类是相对独立的,但在逻辑上是重复的 (这样的代码非常糟糕)。


sort2 方法使用了一个局部类的两个实例。这是比 sort1 更好的方法,但这并不是最有效率的。


sort3 和 sort4 方法分均是使用的一个类的一个实例,它们在逻辑上也没有重复,所以是比较有效率的代码。这两段代码也有不同之处:sort3 比 sort4 更简捷,但 sort4 更具可读性。除了可读性,在这种情况下使用局部类没有更多的意义。


如果你需要在一个应用程序中使用同一种排序的策略,那么上述的四种方法都不是完全正确的。这种情况下,最好使用一个全局类或者内部类 (MyComparator),或者创建一个单独的可用于应用程序中任何地方的比较器实例。sort5 就是这种情况下的例子。


关于匿名类的另一个问题是它们必须基于一个已经存在的类或者接口创建,例如,你使用下面这句代码的时候:


Comparator c = new Comparator() {...};


实际上发生的事情是:从一个没有名字的类创建了实例,而这个类实现了 Comparator 接口。而对于局部类则没有这种限制。


匿名类和局部类更深层次的区别在于:匿名类不能定义构造器,因为它是没有名字的。不过它还是可以通过 {...} 格式的初始化代码块做一些简单的初始化,例如:


import java.util.*;


public class LocalDemo3 {


public static void main(String[] args) {


Comparator cmp1 = new Comparator() {


{


System.out.println(


);


}


public int compare(


Object o1, Object o2) {


int cc = ((Integer)o1).compareTo(o2);


return (cc < 0 ? 1 : cc > 0 ? -1 : 0);


};


};


class MyComparator implements Comparator {


public MyComparator(int x) {


System.out.println(


+


< with value > + x);


}


public int compare(

Object o1, Object o2) {


int cc = ((Integer)o1).compareTo(o2);


return (cc < 0 ? 1 : cc > 0 ? -1 : 0);


};


};


Comparator cmp2 = new MyComparator(100);


}


}



这段程序将输出:



object initialization


constructor called with value 100



局部类可以拥有通过常规方法使用的构造器,而匿名类地必须通过 {...} 来实现初始化。



再次考虑关于对例表进行排序的例子。为局部类或内部类定义一个构造器,并通过传递参数的办法可以指定这个类的实例在操作过程中是按升序还是降序。在匿名类中要做到这一点则需要定义一个类成员级别的 final 变量。



在对类的主流应用中更适合使用局部类,因为你更熟悉。局部类也比匿名类更具可读性。同时,局部类的功能往往会超出你所需要的,那么这个时候,就更适合使用匿名类了。 (全文完)