錯誤:在jdk1.6或jdk1.7運行代碼時,出現如下錯誤,提示找不到此方法
Exception in thread "main" java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetView;
原因:代碼中調用了ConcurrentHashMap<K, V>的keySet()方法,但是這個方法在jdk1.8中發生了改變
jdk1.6/1.7中:
public Set<K> keySet() { Set<K> ks = keySet; return (ks != null) ? ks : (keySet = new KeySet()); }
jdk1.8中:
public KeySetView<K,V> keySet() { KeySetView<K,V> ks; return (ks = keySet) != null ? ks : (keySet = new KeySetView<K,V>(this, null)); }
這是
高編譯低運行導致的錯誤:class文件是jdk1.8編譯的,運行時用的卻是jdk1.6/1.7。
解決方法:
- 解決方法1:使用Eclipse修改編譯時的jdk版本
1).在pom中將編譯的jdk版本改為jdk1.6/1.7,在jdk1.6/1.7運行時還是報一樣的錯
2).在pom中將編譯的jdk版本改為jdk1.6/1.7,在jdk1.8運行卻沒問題?
3).繼續深入,發現使用eclipse的maven插件編譯的時候,jdk版本需要手動指定,pom里指定了沒有用……

最終,在
JRE中手動指定jdk版本,然后打包運行,沒有這個錯了。

- 解決方法2(推薦):面向接口編程
將ConcurrentHashMap改成ConcurrentMap,即可解決 ConcurrentHashMap.keySet 返回參數不一致的問題。
總結:
1.編譯和運行時用的jdk版本最好一致,如果不能保證盡量使用較低版本的jdk編譯。
2.面向接口編程,因為接口不易改變,但是方法的入參和出參可能改變。
3.使用eclipse的maven插件時,需要手動選擇jdk版本。
4.注意maven版本對jdk版本的要求,如果使用低版本的jdk來編譯,那么可能需要使用相應低版本的maven。

