如何避免引用了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.j锾攒揉敫ar。输入命令: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下运行,发现可以正常运行了