可以在较新的JRE上运行较旧的Java程序时使用更新的Java API吗?

huangapple go评论73阅读模式
英文:

Can I use newer Java APIs when running older Java programs with a newer JRE

问题

我有一个Java 8应用程序,我使用Java 17编译器编译成了Java 8字节码。所以sourcetarget都是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.

huangapple
  • 本文由 发表于 2023年7月6日 18:58:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76628100.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定