Java 面向对象的语言,相信很多人都知道Java 的三大面向对象特征 封装 , 继承 , 多态 ,其中多态的特点就是 覆盖 和 重载,但是覆盖是有机制规范的,重载机制是例外的,如果给定的API 普通用户根本不知道会具体调用哪个重载的方法,所以会导致参数的错误,一般大家都重写过 判断对象是否为空的这个方法 下面写出示例:
public static boolean notNull(Collection<?> c){
return c == null ? false : c.size() == 0 ? false : true;
}
public static boolean notNull(String str){
return "".equals(str) ? false : null == str ? false : true;
}
public static boolean notNull(Object obj){
return "" == obj ? false : null == obj ? false : true;
}
public static void main(String[] args) {
// col 是运行了 集合的重载方法 obj 运行 object 重载方法 str是运行 String 重载方法
List list = null;// col
Set set = null;// col
Map map = null ;// obj
int i
= 0; // obj
String str = null;// str
long l = 0l;// obj
System.out.println(notNull(list));
System.out.println(notNull(set));
System.out.println(notNull(map));
System.out.println(notNull(i));
System.out.println(notNull(str));
System.out.println(notNull(l));
}
可能大家已经看出来了 因为 List 和 Set 继承 Collection 集合 Map 没有继承Collection 集合 所以Map 运行 Object 的重载方法,在实际项目中可能会出现问题
这个可能不会有很大影响 但是 JDK 1.5 发布之后 自动装箱出现 才出现更大的问题
下面请看示例
Set<Integer> set = new TreeSet<Integer>();
List<Integer> list = new ArrayList<Integer>();
for(int i = -3, x = 3; i < x; 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]
为什么 Set 输出的对了呢,List的输出的错了呢 这就是 重载的问题了,set.remove(i); 实际调用的是 Set.remove(E e); 可以理解是 Set.remove(Integer i);
这样 i 就会自动装箱到 Integer 了 输出的就是我们想要输出 而 list.remove(i); 调用的是 List.remove(int i); 它从列表指定的位置去除元素,如果从列表
[-3, -2, -1,0,1,2] 开始 去除第0个元素 是 -3,去除第 一个是 -1 ,第二个是 1 所以的到的 结果也是 必然的但是编译器不好检查出来罢了 知道问题出在哪里也就好解决了
for(int i = 0; i < 3; i++){
set.remove(i);
list.remove((Integer)i);
}
强转 为 Integer 就解决问题
输入
[-3, -2, -1] : [-3, -2, -1]
什么情况不要用重载呢 这点本人意见 不要写两个 参数个数一样的重载方法 ,这样容易混乱,如果方法的参数是可变的参数,请你不要重载它,不重载我们可以从新命名呗,这样会避免一些错误。