Don’t call it a comeback: Java is still champ
The JVM is pretty great. I could certainly nitpick things, but it&#x27;s pretty great. Java is pretty decent. However, I would say that Java lost a lot of time and even now there are some decently rough edges.<p>Java didn&#x27;t evolve as a language for a while and that left the door open to other languages and other non-JVM ecosystems a lot. As the article notes, Java 8 was a breath of fresh air, but it was minimal in some ways. Lambdas and streams were great additions to the language. However, Java 8 came out in 2014. That&#x27;s quite late to the game, in my opinion.<p>C# is probably the closest competing language&#x2F;ecosystem (albeit constrained to Microsoft for much of its life). In 2007 (7 years earlier) C# 3.0 had lambdas, the `var` keyword, properties, object initializers, the equivalent of streams (and really better), nullable types for value types (like int), etc. In some ways, Java has caught up - and C# lost a lot of time being constrained to the Microsoft ecosystem. However, in other ways it hasn&#x27;t.<p><i>I just want a POJO</i>: frankly, this has been a problem that Java hasn&#x27;t solved and it&#x27;s been well over a decade where everyone has known it&#x27;s a problem. No, records don&#x27;t solve it. In Kotlin, I can make a data class and it&#x27;s easy. In Scala, I think they&#x27;re case classes. In C# I have properties where I can say: `class Person { string Name { get; set; } }`. I can see that it&#x27;s just a boring property without having to look at method bodies. If there&#x27;s something special, that get or set can have a body to do stuff and it becomes really clear that it&#x27;s something special. Getters and setters are a wonderful way to set traps for others on your team or for yourself a year later because you look at a class with 15 items and it&#x27;s going to have 90 lines of getters&#x2F;setters + another 30 lines of an empty line between each method. You look and just decide &quot;yea, I&#x27;m sure this doesn&#x27;t have special behavior&quot; and go about your business just to get bitten later.<p><i>I want to be able to instantiate data easily</i>: With Java, I can do `var person = new Person(); person.setName(&quot;Johnny&quot;);`, but that becomes pretty tedious and error-prone when instantiating a large object. With records you have a constructor, but then you&#x27;re dealing with positional arguments and it&#x27;s hard to understand. When reading the code, you don&#x27;t necessarily know what each of the inputs means. Maybe your IDE puts the argument names in. When filling it out, I&#x27;ve found IDEs to only be somewhat helpful. With C#, I can do `new Person { }` and then hit the suggestion key combo inside the brackets in my IDE and it&#x27;ll offer to fill out all the properties so that I get something like:<p><pre><code>    new Person {
        Name = &quot;&quot;,
        Age = 0,
        Address = &quot;&quot;
    }
</code></pre>
That means I don&#x27;t forget about fields (as can happen if you&#x27;re just doing `person.setX()` all the time). It&#x27;s easy to see what is what when reading it. I can delete fields I don&#x27;t want to initialize at the time. Yes, maybe immutable objects are the One True Way, but C# lets me choose (I can label properties with an initializer `init` rather than a setter `set` and then they&#x27;re immutable).<p>Kotlin offers stuff like this too because it&#x27;s really useful toward creating code that&#x27;s easy to create and maintain. Go also lets you initialize structs in a similar fashion.<p>Java has come back to us a decade or more late with records. They&#x27;re not bad, but they&#x27;re only offering one thing. They don&#x27;t cover what C#, Kotlin, Go, and other languages have offered for so long.<p>The annoying thing about Java is that it doesn&#x27;t feel pragmatic a lot of the time. It feels like the language hates stealing ideas from others. It&#x27;s Java: people steal ideas from Java, not the other way around. People do crazy things just to get POJOs including Immutables (<a href="http:&#x2F;&#x2F;immutables.github.io" rel="nofollow">http:&#x2F;&#x2F;immutables.github.io</a>), AutoValue (<a href="https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;auto&#x2F;" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;google&#x2F;auto&#x2F;</a>), Lombok (<a href="https:&#x2F;&#x2F;projectlombok.org" rel="nofollow">https:&#x2F;&#x2F;projectlombok.org</a>), Joda Beans (<a href="https:&#x2F;&#x2F;www.joda.org&#x2F;joda-beans&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.joda.org&#x2F;joda-beans&#x2F;</a>), and maybe more. They generate lots of code at compile time or do funky runtime stuff.<p>It just feels like Java misses the pragmatic stuff and still kinda doesn&#x27;t want to handle that. I feel a bit silly harping on things like POJOs and setting data on a new object, but that&#x27;s a big part of day-to-day stuff and it definitely pushes users away from Java towards languages that seem &quot;better&quot; simply because they don&#x27;t have Java&#x27;s oddly strong attachment to not offering simple value objects. Yes, again, records do something - but it feels like Java ignored how people are using Kotlin, Go, C#, and more and didn&#x27;t go for something that would have been as widely applicable and pragmatic as it could have been.<p>Java has a lot of great stuff like great GCs (yes), lots of cool research, great performance, and Project Loom is really exciting. I just wish the language would lean a little more practical.