Java高編譯低執行錯誤 (ConcurrentHashMap.keySet)
阿新 • • 發佈:2018-11-17
這個concurrentHashMap困惑已久,一直以為這個方法是通用的,沒有理會,但是月底的考核沒有定時生成,伺服器日誌顯示如下
nested exception is java.lang.NoSuchMethodError:
java.util.concurrent.ConcurrentHashMap.keySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetView;
在javac指定了這些引數,降低版本號來編譯,會導致生成class檔案被標識為較低版本以供指定的JVM載入。但是,基於JDK 8的bootstrap class編譯而成的keySet()方法,其返回值依舊是JDK 8中ConcurrentHashMap$KeySetView這個新增內部類。執行時,1.7的JVM嘗試載入這個class檔案,一定找不到KeySetView作為返回值的keySet()方法,出錯。
解決方法:
- 編譯期間,替換掉bootstrap class
- 使用父類/介面替換子類,即ConcurrentMap替換ConcurrentHashMap宣告
- 保證編譯、打包環境和最終部署環境JDK版本的一致性
- 如果無法保證,就儘量面向介面程式設計,尤其是JDK中提供的類。原因是介面不易改變,而實現類遵循“寬收嚴發”原則,方法的入參和出參都是易變的。
為難我們運維了,需要更新線上的jdk版本 ~