1. 程式人生 > >Java高編譯低執行錯誤 (ConcurrentHashMap.keySet)

Java高編譯低執行錯誤 (ConcurrentHashMap.keySet)

這個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版本 ~