Java started in 1995 as a clean simple object-oriented language with garbage collection. It was good reactionary software, designed before modern programming ruined software. Java was a big improvement over C++ and I started using Java from the beginning.
Java went through many releases. The last useful addition was in 2006 after which it only declined. The last usable release was Java 8 in 2014. After this, Java was totally ruined by modern programmers and became completely unusable. So I suggest using Java 8.
Here is the history of Java copied from here:
- Java 1.0 was release in 1995.
- Java 1.1 (1997) added reflection which was good. It also added inner classes which had problems as I discussed here.
- Java 1.2 (1998) didn't change the language.
- Java 1.4 (2002) added "assert" which is harmless though I don't use it.
Java 1.5 (2004) added many features.
- Added generics which is horrible mess. Some solution to generics was needed, but this overcomplicated disaster wasn't the right solution. To be honest, I haven't thought through how this should be done. But even C++'s approach is better than Java generics. My suggestion is to only use generics when it is painless. As soon as some complication arises, just dump generics instead of struggling to figure things out.
- Added annotations. This is harmless and can be ignored. I have played with it but never found a real need for it.
- Added autoboxing. I don't like this in theory, but in practice it seems harmless. I use it.
- Added enumerations. This isn't too bad but I hardly use it.
- Added varargs. This is a good feature.
- Added the for-each loop. This is a good feature.
- Added static imports. This is purely a bad feature. It does nothing but reduce readability and it should never be used.
- Java 1.6 (2006) added the compiler API. This is a good feature and I use it to compile Luan.
- Java 1.7 (2011) had no significant language changes.
- Java 1.8 (2014) added lambda expressions which is a complete horror. I have never used them. They are basically depraved pseudo-closures implemented like broken anonymous inner classes. Besides suffering from all the flaws of inner classes, they are syntactically horrible and unreadable. And they don't conceptually fit in Java at all.
I had read about later versions of Java and I knew that it was just getting worse. For example, local-variable type inference is a horrible idea. But when I finally tried to use Java 11, it was far worse than even I expected. They added a new horrible feature Java Modules that not only made Java very complicated, but also completely broke backward compatibility so this feature can't just be ignored. You can find the whole story here. This Java change was so horrible that even some modern programmers complained. The end result is that I will never use a Java version beyond Java 8, and Luan requires Java 8.
This story of the destruction of Java by modern programmers applies to all projects being maintained by modern programmers. Modern programmers can only make software worse, so one should never upgrade any software being maintained by modern programmers. In the case of Java, I suggest sticking with Java 8.