Effective-Java(Item 41)之小心地使用重载

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36336003/article/details/83988599

先说一下重载与重写的区别,很多人会把这两个概念混淆:

1.重载是静态的,发生在compile时期,由编译时类型决定调用方法,通常出现在=号左边的为编译时类型,如Collection<?>[] collections = {};中编译时类型为Collection;
重写是动态的,发生在runtime时期,根据运行时对象调用对应方法;

2.重载发生在一个类中,要求方法名相同,参数列表不同;
重写发生在祖先类和子孙类中,要求返回值、方法名、参数列表完全一致,子孙类throws的异常不得大于祖先类异常,子孙类访问修饰符不得低于祖先类;

// Broken! - What does this program print?
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));
    }
}

输出居然是3次Unknown Collection,因为collections的每个元素的编译时类型是Collection<?>,重载时调用都是classify(Collection<?> c);方法;

重载可以先考虑下面这些情况:

使用instanceof来判断对象类型替代重载
public static String classify(Collection<?> c) {
    return c instanceof Set ? "Set" :
           c instanceof List ? "List" : "Unknown Collection";
}   
给方法不同的名字替代重载
// java.io.ObjectOutputStream
使用writeBoolean(boolean),writeInt(int)和writeLong(long)方法而不是重载write方法

猜你喜欢

转载自blog.csdn.net/qq_36336003/article/details/83988599