Short.compare NoSuchMethodError
起因
项目中需要对数据排序,故需要比较数据属性值的一些大小,而看到Short/Integer/Long/Boolean这些类中,有compare方法可以使用,于是用了起来。
Crash
4.3及以下系统版本,运行到Short.compare时,程序崩溃,堆栈如下:
java.lang.NoSuchMethodError: java.lang.Short.compare
at com.rentee.comparedemo.MainActivity.xxxxxx
疑惑1
为啥崩,看堆栈是没这个方法,于是认真看下API介绍,Short.compare since java 1.7,好吧,应该是"超纲"了,但为啥Lint没有提示呢?
随即AS直接新建了一个demo,发现demo是有Lint提示的:
Call requires API level 19 (current min is 14): java.lang.Short#compare
Hello为啥没有,怀疑Lint配置错了?至今调查未果,懂的大佬支个招?因为Lint NewApi告警是在的,其他"超纲"的都报,暂时发现的,就这个compare,hello工程没检测到。
疑惑2
为啥Short.compare崩,而Integer.compare/Long.compare/Boolean.compare没崩?
xref上查了波Android 4.3源码,发现即使java 1.6,已经有了compare方法,只是标记了@hide
Integer.compare
Long.compare
Short.compare
你没看错,Short.compare中传入的参数是2个long。没理解,这个compare是从long复制过来的么,jdk hide的api质量这么…
而java 1.7中,Short.compare传参确实是short
疑惑3
long字长大于short,对于低版本Short.compare,java为何没有将传入参数自动转型,从而在低版本java上调用compare(long a, long b)?
思考一下,转型过程应该是在编译器完成的,于是写了以下代码进行验证
反编译代码如下:
如所料,是在编译期完成的。那么如果我们将compileSdkVersion改为19以下呢?
对不住,由于compare是hide的,不给调。不过上面也足以验证猜想了。