问题一,故事将遵循:
它是安全的类层次混合不同的字节码的版本? 什么是风险?
为的情况下,C类延伸B,B类延伸的A类。A类实现接口I.我的问题将涉及下面的示例方案:
- 一类编译成Java字节码1.6,并具有1.6的功能,如泛型等的继承者,其是B和C被编译为字节码1.4。
- 接口I编译为1.6,而实施者编译为1.4。
- 其他外来遗传场景涉及到不同版本的字节码。
我试图尽可能多的情况下,我可以想像,它似乎运行得很好。 不过我还是觉得冲动,问这里我仅在表面了解Java; 我知道如何编写和调整Java,但真的不知道引擎盖下怎样就怎样。
现在,对于那些头脑谁也帮不了自己问:“为什么你需要做的???”。
我在一个项目,评估遗留Java 1.4 Swing应用程序的迁移,通过RMI连接到EJB 2,Java 1.6的秋千连接到1.6也上运行应用程序服务器的新版本。 J2EE平台将仍然是1.4(EJB 2)。
迁移将不会是“重新编译所有到1.6”,但是这将是“代码和编译的新功能,1.6”。 他们做事的方式是这样的:他们只有在CVS一个路径,每个人都犯有。 没有标签/分支任何获得生产代码。 每当添加一个新的功能需求,他们得到的JAR文件从生产服务器,它们爆炸,更换或添加新的类可以根据需要,重新包装的广口瓶,将它们发送回服务器。 因此,如果他们将使用Java 6编译和使用部署上面的方法,将有大量的1.4和1.6字节码异国混合的。
JVM的字节代码是不是Java 1.0和Java 6之间siginificantly不同在Java 7它们添加一个新的指令。 哇噢。
有在字节代码是如何工作的,这么小的变化
- 在JVM不支持嵌套类访问外部类的私有成员,这是通过生成的代码。
- 在JVM不支持运行时检查泛型例如,你不能
new T()
其中T是通用的。
基本上,他们使JVM更智能,更快,但直到最近才改变如何字节代码工作已经避免不惜一切代价的模式。
您可以使用Java 6编译,但目标1.4编译器设置。 我们这样做是为了迁移项目一次。 如果/当1.4消失,然后你再次更改编译器设置和目标1.6。
保持目标明确的版本也意味着你可以升级你的SDK,而不用担心你的JAR文件中不能使用的一个老版本的JVM。
我保持与1.4组合(旧库罐)和1.5(我的修复和东西)班Tomcat上使用Sun JVM 1.5的环境中,并运行良好。
然而,RMI你可能有麻烦,如果客户端和服务器都有不同的类版本,因为服务器会检查类版本(我就遇到了这个问题)。
找出最好的办法是做小规模项目的概念类型的证明。
一个友好的提醒,虽然,你挖一个非常大洞为自己在这里:-)
这些链接似乎有关。 他们记录了一些边缘的情况下,可能破坏兼容性之间和1.5 1.4和1.5和1.6之间 。
可能导致我能想到的是,枚举成为一个关键词的问题,但装载旧的类文件(这似乎并不为你会做什么)时,只会影响一个JVM中1.5+的最大区别。 另一件事是注释。 上面的链接似乎表明一切都很好,但我会警惕,如果旧的JVM加载了运行时注解类会发生什么。
除此之外,我不认为有过的Java的第一个版本和Java 6之间的任何字节码改变这意味着你应该遇到的唯一问题是改变功能的API或弃用(在上面的链接中列出)。
只要你不使用反射,唯一的重大问题,你可以有不同的,从字节码版本是ACC_SUPER
标志。
在非常早期的版本中,超类方法调用不正确处理。 当他们固定的,他们增加了一个新的标志类文件格式, ACC_SUPER
启用它,以便应用程序依赖于旧,破,行为并没有受到影响。 当然,使用不含有此标志的类可能会导致问题。
然而,这是古老的历史。 每个类都在1.4编译和以后有标志,所以这不是一个问题。 字节码明智,1.4和1.6之间的唯一的主要区别是用于存储有关内部类,泛型,注释等的元数据添加可选属性
然而,这些不直接影响字节码执行。 这些具有影响的唯一方法是,如果你通过反射访问它们。 例如, java.lang.Class.getDeclaredClasses()
将返回从可选属性信息InnerClasses
。