1.由于重载调用哪个方法是在编译时做出的决定,所以很容易造成调用了出乎意料重载方法的情况,比如以下例子,它最后输出了三个Unkown Collection。
public class CollectionClassifier {
public static String classify(Set<?> s) {
return "Set";
}
public static String classify(List<?> lst) {
return "List";
}
public static String classify(Collection<?> c) {
return "Unknown Collection";
}
public static void main(String[] args) {
Collection<?>[] collections = {
new HashSet<String>(),
new ArrayList<BigInteger>(),
new HashMap<String, String>().values()
}
for (Collection<?> c : collections)
System.out.println(classify(c));
}
}
2.重写方法是在运行时决定调用哪个方法,所以编译时的类型不会影响最终调用哪个方法。
3.最安全的方式是不要导出两个参数数量相同的重载方法。如果用了可变参数,那就不要重载它。只要取个不一样的名字就可以避免重载的麻烦.
4.对于构造器可以用静态工厂代替。
5.自动装箱可能导致调用错重载方法。
public class SetList {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<>();
List<Integer> list = new ArrayList<>();
for (int i = -3; i < 3; i++) {
set.add(i);
list.add(i);
}
for (int i = 0; i < 3; i++) {
set.remove(i);
list.remove(i);
}
System.out.println(set + " " + list);
}
}
以上代码最后输出为 [-3,-2,-1] [-2,0,2] , 主要原因是list.remove(i)调用选择重载方法remvoe(int i),它从列表的指定位置上去除元素。它没有按预期自动装箱后调用 remvoe(Integer i)。
6.不要再相同参数位置调用不同函数接口的方法。
思考;
1.相同参数数量的重载方法应当避免,一方面不确定使用时是否能调用预期方法。另一方面可读性也会变差,看到一个方法调用还要甄别是哪个重载方法。在写方法时,需要注意避免同名方法,一种方式是先写调用,后生成方法,IDE会提示是否已经有这个方法名的方法了,还有就是在调用方法时,要注意是否有同名方法,如果有,需要查看是否需要重命名后去除重载。