<div dir="ltr">Starting from Java 9, Java began to iterate rapidly and introduced<br>many new features, which made Java more expressive and modern.<br><br>However, upgrading Java is always difficult and painful. It needs to <br>go through a series of cumbersome upgrade and migration processes.<br>In these steps, the transplantation at the syntax level is often easy,<br>because Java maintains good compatibility. However, due to subtle <br>changes in the behavior of the JVM and the standard library, it is <br>relatively difficult to upgrade the version of the java runtime.<br>At the same time, for client applications, upgrading the development <br>environment is much easier than upgrading the Java version of the <br>deployment environment (e.g., only Java 8 is currently available on <br>MIPS64el). For various reasons, a large number of users stay on the<br>old java version. According to the statistical report of JetBrains, <br>71% of users still regularly use Java 8.0 in 2021. <br><br>The most affected people are the developers of libraries. In order to<br>make the library more widely used, most library authors always need to<br>make their libraries use the lowest java version possible. This makes <br>it difficult for them to enjoy the expression upgrade brought by Java <br>update.<br><br>This pain is not necessary. Although some language features of Java <br>require the cooperation of JVM and standard library, e.g. Record, but <br>this is not necessary for more features. At present, we can specify <br>the source version and target version respectively, but we can't make<br>the source version higher than the target version. I think this <br>artificial additional restriction can be removed after careful <br>consideration, so that more developers can enjoy the improvement of<br>expression ability brought by Java's new language features.<br><br><br>These features are pure language features that can be easily compiled <br>into older versions of Java bytecode:<br>  <br>  * Milling Project Coin (JEP 213): Allow @SafeVargs on private instance <br>  Â  methods; Allow effectively-final variables to be used as resources <br>  Â  in the try-with-resources statement;Allow diamond with anonymous <br>  Â  classes if the argument type of the inferred type is denotable.<br>  Â  <br>  * Local-Variable Type Inference (JEP 286)<br>  * Local-Variable Syntax for Lambda Parameters (JEP 323)<br>  * Switch Expressions (JEP 361)<br>  * Text Blocks (JEP 378)<br>  * Pattern Matching for instanceof (JEP 394)<br>  * Pattern Matching for switch (JEP 406)<br>  * Record Patterns & Array Patterns (JEP 405)<br>  <br>  <br>These characteristics cannot be directly desugared, but can be accepted<br>by the old runtime: <br><br>  * module-info.java (JEP 261): At present, it is a popular practice to<br>  Â  use Java 8 compilation library and add module info to it. However, <br>  Â  this practice has not been well supported by the official. Even <br>  Â  with a build tool like gradle, it needs to be implemented by <br>  Â  special means. If javac can accept module info when the target <br>  Â  version is less than 9 and compile it to Java 9, it is very helpful<br>  Â  to simplify modular existing code.<br>  Â  <br>  * Allow interface methods to be private (JDK-8071453): This seems to<br>  Â  be allowed in jvmls 8, but it was not until Java 9 that it was <br>  Â  introduced into the Java language.<br>  Â  <br>  * Sealed Classes (JEP 409): Javac generates PermittedSubclasses_attribute<br>  Â  for sealed classes. This attribute will be ignored on the old <br>  Â  runtime and will not destroy the program. Even if it cannot be <br>  Â  guaranteed by the runtime before JDK 15, it can enhance the <br>  Â  expressiveness of the language and make the code more compatible <br>  Â  with the higher version runtime.<br>  Â  <br>  * Universal Generics (JDK-8261529): Universal generics seem to <br>  Â  compile well into bytecode compatible with older Java version.<br>  Â  I think it is particularly important to allow use of universal <br>  Â  generic in older bytecodes. This allows the library to adapt it<br>  Â  without compromising compatibility with older Java versions. This <br>  Â  can erase many obstacles to Valhalla's promotion.<br>  Â  <br><br>Now we can use some hacks to do similar things, like<br><br>  <a href="https://github.com/bsideup/jabel">https://github.com/bsideup/jabel</a><br>  <br>But this is just hack. It is unofficial and non-standard. At the same <br>time, it also lacks tool support. <br><br>We can also choose to switch to kotlin or Scala, both of them can emit<br>Java 8 bytecode. In fact, because of the need for compatibility, the <br>new language features of Java can't bring us more attraction because <br>we can't use it most of the time. Over time, kotlin and Scala, which <br>can have more language features on Java 8, have attracted us more and<br>more. These problems are not just in the Java 8 era. The need to be<br>compatible with old Java versions always exists, which makes it difficult<br>for many people to put new features of the Java language into production<br>for a long time. This will make Java less competitive with other JVM <br>languages.<br>  Â Â <br></div>