Effective-Java(Item 41)之小心地使用過載
阿新 • • 發佈:2018-11-12
先說一下過載與重寫的區別,很多人會把這兩個概念混淆:
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方法