我对合规模式有疑问。 我的类扩展了一个基本的java类,例如Properties,用JDK5编译并打包到jar中。现在我在一个项目中使用这个jar,该项目使用JDK 6进行构建,但是在合规模式5中。 有人现在可以在JDK6项目的类中使用新方法stringPropertyNames() - 它是JDK6中的新东西吗?
答案 0 :(得分:3)
只要您在JRE 6 JVM上运行项目,它就可以正常运行。而且您不需要编译符合Java 1.5的项目。也就是说,在编译项目时,您不需要使用-source 1.5
或-target 1.5
选项。
另一方面,当您在JRE 5 JVM上运行项目时,它将失败并带有
java.lang.NoSuchMethodError:B.stringPropertyNames()Ljava/util/Set;
无论编译项目时使用的选项如何。
在运行时发生的事情是,JVM搜索Properties.stringPropertyNames()
的相应执行字节码。在JRE 6上运行时,存在这样的代码(无论编译中使用了哪些选项)。在JRE 5上运行时,它不存在。
我检查了你建议的情景:
B.java:
public class B extends Properties {
public B() {
setProperty("a", "aaa");
setProperty("b", "bbb");
}
}
C.java:
public class C {
public static void main(String[] args) {
B b = new B();
System.out.println(b.stringPropertyNames());
}
}
以下输出结果相同,使用-source 1.5
和/或-target 1.5
或不使用JDK 6进行编译。
JVM 6上的输出:
[b, a]
JVM 5上的输出:
Exception in thread "main" java.lang.NoSuchMethodError: B.stringPropertyNames()Ljava/util/Set;
at C.main(C.java:17)
那么,为什么要在编译中使用-source
和-target
?
This site简洁地解释说,如果使用晚于指定版本的某些版本功能,则可以使用-source
选项使编译器失败。例如,-source 1.4
确保您不使用泛型(否则只会在运行时失败)。
根据official docs,-target
选项用于在其他(早期)JVM上执行已编译的代码。例如,如果我使用JDK 6编译我的代码但我需要它在JVM 5上运行,我会在编译时使用-target 5
。如果我不这样做,我会得到java.lang.UnsupportedClassVersionError: Bad version number in .class file
。
我希望你不会被答案所淹没;)......