7.41 谨慎使用方法重载(overloading)

以下类对不同的集合类型分类,classify()方法被重载:

 

public class CollectionClassifier {
	public static String classify(Set<?> s){
		return "Set";
	}
	
	public static String classify(Collection<?> c){
		return "Collection";
	}
}

 

 

以下测试将失败:

	@Test
	public void testCollectionClassifier(){
		Collection<String>  c=new HashSet<String>();
		
		//因为c声明为Collection类型,而重载方法的选择是在编译时决定的,
		//所以最终会调用classify(Collection<?> c)
		Assert.assertEquals(CollectionClassifier.classify(c), "Set");
	}

 

重载方法的选择是在编译时决定的(即为静态选择,而覆盖方法的选择是在运行时选择的,即动态选择),如果被重载的方法具有相同的参数个数,并且参数类型之间具有继承关系(如上例参数类型Set继承Collection),那么可能导致问题。

 

List的remove(int)、remove(Object)使用了重载,对List<Integer>类型,在调用remove()方法时应注意区分:

	@Test
	public void testList(){
		List<Integer> list=new ArrayList<Integer>();
		
		//-1,0,1将被自动转型为Integer类型
		list.add(-1);
		list.add(0);
		list.add(1);
		
		//因为参数为int类型的1,所以会调用list.remove(int)
		Assert.assertEquals(list.remove(1), Integer.valueOf(0));
		
		//因为参数为Integer类型,所以会调用list.remove(Object)
		Assert.assertEquals(list.remove(Integer.valueOf(1)), true);
	}

 

使用方法重载的基本原则:

1.重载的方法应具有不同的参数个数

 

2.如果重载的方法具有相同的参数个数,那么参数的数据类型之间不应有继承关系

 

3.使用不同名称的静态工厂方法,以避免多个重载的构造函数

 

4.如果无法避免重载的方法参数个数相同,并且参数之间具有继承关系。那么应调用同一个重载方法,以保证所有的重载方法实现相同的功能。如因为JDK5增加了CharSequence接口,所以String不可避免的出现了方法重载contentEquals(StringBuffer),contentEquals(CharSequence)。但是前者直接调用后者进行比较(String,StringBuffer都实现了CharSequence接口)

 

5.不要重载具有变长参数的方法

 

 

 

 

 

 

 

 

你可能感兴趣的:(overloading)