如何避免引用了jdk高版本api被编译成低版本误用
1、出现错误的情况一般都是引用到超过目标版本的api类和方法,为了演示如何解决,首先需要构造引用高版本的例子。首先看下ConcurrentHashMap类的mappingCount方法,这个方法是在jdk1.8版本添加的

2、添加一个测试类演示下,如图所示,引用了ConcurrentHashMap的mappingCount方法

3、在cmd命令下输入:javac -source 1.7 -target 1.7 Test.java,此时没有添加-bootclasspath参数,会出现以下警告信息,警告: [options] 未与 -source 1.7 一起设置引导类路径,但还是可以正常编译

4、然后将编译后的class文件复制到jdk1.7下面执行,输入java Test命令,运行发现报错了,java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.mappingCount()J,这是因为使用的1.8里的方法,编译默认使用的引导类也是1.8的,所以编译没有保存,但在1.7下面运行就出现错误了

5、解决方法就是,在1.8编译class的时候,带上-bootclasspath参数,然后值路径是1.7的引导类rt.jar。输入命令:javac -bootclasspath E:\rt1.7.jar -source 1.7 -target 1.7 Test.java,此时发现编译的时候就提示错误了,不能编译成功。这样的话,提早暴露了错误,不会存在误用的情况

6、下面再来看一个比较隐蔽容易出错的地方,就是ConcurrentHashMap的keySet方法,如图所示是1.7的方法,返回值为Set

7、切换到1.8的ConcurrentHashMap类的keySet方法,则可以看到返回值变成了KeySetView

8、添加一个例子使用了这个ConcurrentHashMap类的keySet方法

9、如果编译的时候没有带上执行bootclasspath参数,同样可以正常编译通过,但运行的时候发现,报错了。其实这个源码文件本身是没有问题的,可以在1.8和1.7下运行,只是编译的时候没有带上bootclasspath正确的引导jar,使用javac -bootclasspath E:\rt1.7.jar -source 1.7 -target 1.7 Test.java编译之后再次放到1.7下运行,发现可以正常运行了
