<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>