关于JDK编译版本详解

来源:互联网 发布:商家入驻一元夺宝源码 编辑:程序博客网 时间:2024/06/01 07:35

minor.major version 详解


1.Eclipse中三个JDK版本的含义

1.1 Compiler compliance level:使用编译器的版本

1.2 Generated .class files compatibility:生成的class文件在什么版本JDK下运行

1.3 Source compatibility:源代码和哪个版本JDK兼容

 

上例表示,需要用JDK1.7编译,二进制包需要JDK 1.6及以上环境运行,源代码只能用JDK1.5的语法。

一直以来都是用jdk1.5,这次重返电信由于其系统是在jdk1.4上编译的,编译的时候出现了unsupported major.minor version49.0的错误,上网查看了一下还是一个很普遍的错误,捣鼓了两天终于捣鼓出一些东西,现分享给大家。

     何谓 major.minor,且又居身于何处呢?先感性认识并找到 major.minor 来。顺便写一段 代码,然后用 JDK 1.5 的编译器编译成class,用UltraEdit或者其他能打开非十进制文件的软件打开此class,见下图:        

 

       从上图中我们看出来了什么是 major.minor version 了,它相当于一个软件的主次版本号,只是在这里是标识的一个 Java Class 的主版本号和次版本号,同时我们看到 minor_version 为 0x0000,major_version 为 0x0031,转换为十制数分别为0 和 49,即 major.minor 就是 49.0 了。

      现在不妨从 JDK 1.1 到 JDK 1.7 编译器编译出的 class 的默认 minor.major version 吧。(又走到 Sun 的网站上翻腾出我从来都没用过的古董来)
     

JDK 编译器版本target 参数十六进制 minor.major十进制 minor.majorjdk1.1.8不能带 target 参数00 03 00 2D45.3jdk1.2.2不带(默认为 -target 1.1)00 03 00 2D45.3jdk1.2.2-target 1.200 00   00 2E46.0jdk1.3.1_19不带(默认为 -target 1.1)00 03 00 2D45.3jdk1.3.1_19-target 1.300 00   00 2F47.0j2sdk1.4.2_10不带(默认为 -target 1.2)00 00   00 2E46.0j2sdk1.4.2_10-target 1.400 00   00 3048.0jdk1.5.0_11不带(默认为 -target 1.5)00 00   00 3149.0jdk1.5.0_11-target 1.4 -source 1.400 00   00 3048.0jdk1.6.0_01不带(默认为 -target 1.6)00 00   00 3250.0jdk1.6.0_01-target 1.500 00   00 3149.0jdk1.6.0_01-target 1.4 -source 1.400 00   00 3048.0jdk1.7.0不带(默认为 -target 1.6)00 00   00 3250.0jdk1.7.0-target 1.700 00   00 3351.0jdk1.7.0-target 1.4 -source 1.400 00   00 3048.0Apache Harmony 5.0M3不带(默认为 -target 1.2)00 00   00 2E46.0Apache Harmony 5.0M3-target 1.400 00   00 3048.0

 

       当然你也可以用其他方法查看版本号,比如javap -verbose XXXX(class名)。

        那么现在如果碰到这种问题该知道如何解决了吧,还会像我所见到有些兄弟那样,去找个 1.4 的 JDK 下载安装,然后用其重新编译所有的代码吗?且不说这种方法的繁琐,而且web应用程序还不一定能成功,其实大可不必如此费神,我们一定还记得 javac 还有个 -target 参数,对啦,可以继续使用 1.5 JDK,编译时带上参数 -target 1.4 -source 1.4 就 OK 啦,不过你一定要对哪些 API 是 1.5 JDK 加入进来的了如指掌,不能你的 class 文件拿到 JVM 1.4 下就会 method not found。目标 JVM 是 1.3 的话,编译选项就用 -target 1.3 -source 1.3 了。

      相应的如果使用 ant ,它的 javac 任务也可对应的选择 target 和 source

<javac target="1.4" source="1.4" ............................/>

如果是在开发中,可以肯定的是现在真正算得上是 JAVA IDE 对于工程也都有编译选项设置目标代码的。例如 Eclipse 的项目属性中的 Java Compiler 设置,如图:

        

        其实理解 major.minor 就像是我们可以这么想像,同样是微软件的程序,32 位的应用程序不能拿到 16 位系统中执行那样。

如果我们发布前了解到目标 JVM 版本,知道怎么从 java class 文件中看出 major.minor 版本来,就不用等到服务器报出异常才着手去解决,也就能预知到可能发生的问题。

其他时候遇到这个问题应具体解决,总之问题的根由是低版本的 JVM 无法加载高版本的 class 文件造成的,找到高版本的 class 文件处理一下就行了。


从 JDK 1.1 到 JDK 1.7 编译器编译出的 class 的默认 minor.major version 吧。(又走到 Sun 的网站上翻腾出我从来都没用过的古董来)

JDK 编译器版本target 参数十六进制 minor.major十进制 minor.majorjdk1.1.8不能带 target 参数00 03   00 2D45.3jdk1.2.2不带(默认为 -target 1.1)00 03   00 2D45.3jdk1.2.2-target 1.200 00   00 2E46.0jdk1.3.1_19不带(默认为 -target 1.1)00 03   00 2D45.3jdk1.3.1_19-target 1.300 00   00 2F47.0j2sdk1.4.2_10不带(默认为 -target 1.2)00 00   00 2E46.0j2sdk1.4.2_10-target 1.400 00   00 3048.0jdk1.5.0_11不带(默认为 -target 1.5)00 00   00 3149.0jdk1.5.0_11-target 1.4 -source 1.400 00   00 3048.0jdk1.6.0_01不带(默认为 -target 1.6)00 00   00 3250.0jdk1.6.0_01-target 1.500 00   00 3149.0jdk1.6.0_01-target 1.4 -source 1.400 00   00 3048.0jdk1.7.0不带(默认为 -target 1.6)00 00   00 3250.0jdk1.7.0-target 1.700 00   00 3351.0jdk1.7.0-target 1.4 -source 1.400 00   00 3048.0Apache Harmony 5.0M3不带(默认为 -target 1.2)00 00   00 2E46.0Apache Harmony 5.0M3-target 1.400 00   00 3048.0

 


1) -target 1.1 时 有次版本号,target 为 1.2 及以后都只用主版本号了,次版本号为 0
2) 从 1.1 到 1.4 语言差异比较小,所以 1.2 到 1.4 默认的 target 都不是自身相对应版本
3) 1.5 语法变动很大,所以直接默认 target 就是 1.5。也因为如此用 1.5 的 JDK 要生成目标为 1.4 的代码,光有 -target 1.4 不够,必须同时带上 -source 1.4,指定源码的兼容性,1.6/1.7 JDk 生成目标为 1.4 的代码也如此。
4) 1.6 编译器显得较为激进,默认参数就为 -target 1.6。因为 1.6 和 1.5 的语法无差异,所以用 -target 1.5 时无需跟着 -source 1.5。
5) 注意 1.7 编译的默认 target 为 1.6
6) 其他第三方的 JDK 生成的 Class 文件格式版本号同对应 Sun 版本 JDK
7) 最后一点最重要的,某个版本的 JVM 能接受 class 文件的最大主版本号不能超过对应 JDK 带相应 target 参数编译出来的 class 文件的版本号

上面那句话有点长,一口气读过去不是很好理解,举个例子:1.4 的 JVM 能接受最大的 class 文件的主版本号不能超过用 1.4 JDK 带参数 -target 1.4 时编译出的 class 文件的主版本号,也就是 48。

因为 1.5 JDK 编译时默认 target 为 1.5,出来的字节码 major.minor version 是 49.0,所以 1.4 的 JVM 是无法接受的,只有抛出错误。

那么又为什么从 1.1 到 1.2、从 1.2 到 1.3 或者从 1.3 到 1.4 的 JDK 升级不会发生 Unsupported major.minor version 的错误呢,那是因为 1.2/1.3/1.4 都保持了很好的二进制兼容性,看看 1.2/1.3/1.4 的默认 target 分别为 1.1/1.1/1.2 就知道了,也就是默认情况下1.4 JDK 编译出的 class 文件在 JVM 1.2 下都能加载执行,何况于 JVM 1.3 呢?(当然要去除使用了新版本扩充的 API 的因素)



参考资料

 http://blog.csdn.net/xiaxiaorui2003/article/details/4327029

http://www.blogjava.net/Jay2009/archive/2009/04/23/267108.html


0 0
原创粉丝点击