在上一篇《java module解压及java常见打包格式》一文中,我们解包出了class文件,因为class文件是经过java编译过的。是无法直接进行查看的,不过这难不道老司机,打开 jd-gui 工具直接查看源码就行了,不过显然问题想的有点简单了,在jd-gui查看时,发现只有个别class文件可以查看,大部分class文件无法查看,本篇就先是推荐下CFR工具,再是总结下如何区分使用什么java版本编译出的class文件。

一、jd-gui搞不定的class文件

jd-gui
jd-gui

哥满怀激动的打开jd-gui,咖啡杯还是原来的咖啡杯,可却品不出了咖啡的味道,报错了。凌乱十秒,怎么办?找新的工具,找到了新工具CFR ,这个新产生的王者支持java9噢,具体命令如下:

java-decompiler
java-decompiler

虽然是不同的味道,但却品出了熟悉的配方,瞬间感觉碉堡了有木有。

二、如果通过class文件获取使用的java版本

java class文件里包含两个信息:minor_version、major_version,minor_version 和 major_version 的值分别表示 Class 文件的副、主版本。它们共同构成了 Class 文件的格式版本号。譬如某个 Class 文件的主版本号为 M,副版本号为 m,那么这个 Class 文件的格式版本号就确定为 M.m。

还是上面的图片,我在使用cfr工具获取源码之前,还执行了javap命令查看version信息,上面可以看到class文件的版本格式为54.0 ,这个号码和java版本之间是什么关系呢?看下图:

class-java-version
class-java-version

当然这个表有点老,没有列出最新的java9(JDK1.9),java10(JDK10)与class版本号的关系。而上图中的十六进制版本号的作用是什么呢?其实这部分就是前8位内容里的后四位,可能这句话会非常绕口。没关系,看下图:

java-version
java-version

前四位CA FE BA BE内容是固定的,后四位就表示JDK的主版本号与次版本号。通过主版本号计算得出其十进制值,别对应编译器版本,就可以知道其在什么版本下的java下编译出的class文件。