英文:
Can I use newer Java APIs when running older Java programs with a newer JRE
问题
我有一个Java 8应用程序,我使用Java 17编译器编译成了Java 8字节码。所以source
和target
都是Java 8。我之所以这样做,是因为Java 17中的GC算法有许多改进。我做了一些研究,我知道如果我想编译成Java 8字节码,就应该使用Java 8(或更早)的语法。
然后我注意到我不能使用Map.of()
函数,因为这个API被标记为@since 9
,这让我感到困惑。我没有使用任何更新的Java语法。为什么我可以使用Java 17附带的GC算法,但不能使用它附带的标准库呢?
我认为应该是这样工作的:
JRE 17(运行我的应用程序)已经包含了所有Java 17标准库,编译成了Java 17字节码。因此,当JVM遇到Map.of()
(或任何其他被标记为@since 9+
的方法)时,它应该像往常一样运行标准库。
另外,运行Map.of()
特别有什么问题?
英文:
I have a Java 8 application with I compiled to Java 8 bytecode using Java 17. So source
and target
are both Java 8. Why I did this is that there were many improvements in GC algorithms in Java 17. I did a bit of research and I know that I should write in Java 8 (or earlier) syntax if I want to compile to Java 8 bytecode.
Then I noticed I can't use Map.of()
function since the api is marked @since 9
and it confused me. I'm not using any newer Java syntax. Why is it that I can use GC algorithms that come with Java 17 but I can't use standard libraries that come with it?
Here's how I think It should work:
JRE 17 (which runs my app) already containts all Java 17 standard libraries compiled in Java 17 bytecode. So when JVM encounters Map.of()
(or any other methods marked with @since 9+
) it should just run the standard library as usual.
Also, what is the problem with running Map.of()
specifically?
答案1
得分: 1
Java更新时会有一些变化,尽管它应该保持向后兼容。也就是说,除非你在使用已弃用的类,否则你的代码应该能够在新的JDK上编译和运行。
字节码会发生变化,但你可以通过告诉javac“目标”一个较旧的字节码版本来生成兼容的字节码。
此外,源代码也会发生变化。例如,Lambda表达式。在Java 1.6中并不存在,因此你不能使用它们并期望创建1.6兼容的字节码。你可以告诉javac,你只想编译与Java 1.6兼容的源代码,然后你会收到关于Lambda表达式的错误。
一旦你有了兼容的源代码和兼容的字节码,你还会遇到库的问题。这很简单,比如我有一个名为“mylibrary.jar”的库,其中包含一个类“MyClass.class”。我可以通过提供这个库来编译代码,如果你想运行那个代码,你仍然需要这个库。
Map.of
是标准JDK的一个新增功能,因此在1.8 JDK中不存在。它的所有内容都与Java 8兼容,因此它通过了源代码和目标测试。你只需要在运行程序时提供它,就像提供任何其他库一样。
英文:
As java updates a couple things change, although it is supposed to remain backwards compatible. ie unless you're using deprecated classes your code should compile and run with a new jdk.
The bytecode changes, but you can make compatible bytecode by telling javac to "target" an older bytecode version.
On top of that the source code changes. For example, lambda expressions. They didn't exist in java 1.6 so you cannot used them and expect to create 1.6 compatible bytecode. You can tell javac that you want to only compile java 1.6 compatible source code and you'll get an error about lambda expressions.
Once you have compatible source code, and compatible bytecode you have a problem with libraries. This is very simple, say I have a library, "mylibrary.jar" and it has a class "MyClass.class". I can compile the code by providing the library, if you want to run that code. You still need the library.
Map.of
is an addition to the standard jdk, so it doesn't exist in 1.8 jdk's. Everything about it is compatible with java 8, so it passes the source and target tests. You just have to provide it when you run the program. Just like you would any other library.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论