2014-12-02 18 views
8

在互動階控制檯運行下面的代碼斯卡拉允許java.util.HashMap中調用get方法與錯誤的參數數量

val map = new java.util.HashMap[String, Integer](); 

map.put("key1", 5) 

"Test " + map.get("key1") + " " + map.get() + " " + map.get("key1", "key2") + " " + map.get("key1", "key2", "key3") 

返回以下

Test 5 null null null 

我希望這個代碼在第一次調用之外的所有調用get方法的過程中導致編譯器錯誤的參數數量錯誤。爲什麼這個編譯成功並只返回null?

回答

12

Java的地圖不是類型安全的,特別是get方法有此簽名:

public V get(Object key); 

所以,你可以用任何東西作爲重點。 Scala裏,你看到所謂的自動幾倍,而這在斯卡拉2.11棄用,因此,如果您-deprecation編譯你的項目,你會看到:

[warn] ... Adaptation of argument list by inserting() has been deprecated: leaky (Object-receiving) target makes this especially dangerous. 
[warn]   signature: HashMap.get(x$1: Any): V 
[warn] given arguments: <none> 
[warn] after adaptation: HashMap.get((): Unit) 
[warn] "Test " + map.get("key1") + " " + map.get() + " " + map.get("key1", "key2") + " " + map.get("key1", "key2", "key3") 
[warn]           ^

你可以把它轉換成一個錯誤與-Xfuture編譯標誌:

[error] ... Adaptation of argument list by inserting() has been removed. 
[error]   signature: HashMap.get(x$1: Any): V 
[error] given arguments: <none> 
[error] "Test " + map.get("key1") + " " + map.get() + " " + map.get("key1", "key2") + " " + map.get("key1", "key2", "key3") 
[error]           ^

自動裝置幾倍map.get()將被視爲map.get(())map.get("key1", "key2")和將被視爲map.get(("key1", "key2"))

我建議使用Scala自己的集合類型,除非你有一個非常特別的理由不這樣做。

+3

'-Xfuture'似乎只警告空的parens,'-Ywarn-adapted-args'在其他自動tupling的情況下發出警告。 – Dimitri 2014-12-02 22:27:31