zoukankan      html  css  js  c++  java
  • Java高版本编译低版本运行错误(ConcurrentHashMap.keySet)


    发布于: 2018-06-19 11:13:37

    问题

    有个程序,在有些机器会出现清空数据失败的问题,不抛出任何错误,本机无法重现。

    定位问题

    由于不抛出任何错误,只能增加日志, 最终定位到调用ConcurrentHashMap.keySet()方法卡死

    对比出现问题的机器与没有问题的机器,发现出问题的机器JDK版本是1.7, 而没有问题的JDK版本是1.8

    基本可以确定是由于keySet() 方法与JDK 版本不一致导致的问题

    但是我本机pom.xml中已经指定language level 为1.7:

    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
    <source>1.7</source>
    <target>1.7</target>
    </configuration>
    </plugin>
    

    按理应该不会出现版本不一问题

    然后网上看到这篇文章

    得到结论与解决方法

    在javac指定了这些参数,降低版本号来编译,会导致生成class文件被标识为较低版本以供指定的JVM加载。但是,基于JDK 8的bootstrap class编译而成的keySet()方法,其返回值依旧是JDK 8中ConcurrentHashMap$KeySetView这个新增内部类。运行时,1.7的JVM尝试加载这个class文件,一定找不到KeySetView作为返回值的keySet()方法,出错。

    解决方式

    使用父类/接口替换子类,即ConcurrentMap替换ConcurrentHashMap声明

    即使用ConcurrentMap map = new ConcurrentHashMap() 替换 ConcurrentHashMap map = new ConcurrentHashMap()

    结论
    • 保证编译、打包环境和最终部署环境JDK版本的一致性

    • 如果无法保证,就尽量面向接口编程,尤其是JDK中提供的类。原因是接口不易改变,而实现类遵循“宽收严发”原则,方法的入参和出参都是易变的。

  • 相关阅读:
    SGU 499 Greatest Greatest Common Divisor
    pku 3468 A Simple Problem with Integers
    pku2226 Muddy Fields
    pku3041 Asteroids
    java基础string操作
    PowerDesigner(7)转载
    java基础2
    PowerDesigner(6)转载
    java基础3
    java基础(1)
  • 原文地址:https://www.cnblogs.com/qoyi/p/12788632.html
Copyright © 2011-2022 走看看