> you don't have REPL
(ahem) https://docs.oracle.com/en/java/javase/23/jshell/introductio...You don't sound like you work with Java. I know for a fact that even some FANGs, with their army of software engineers, still use Java8 for most of their Java projects.
From what I can tell, there are 4 main reasons why some don't upgrade.
1. They have legacy software and are afraid of breaking it, sometimes with good reasons.
2. The devs don't know or care enough about the new versions to bother with it. Noone is promoted because of an upgrade. Work to live, and don't live to work
3. The ones who don't have buy in from management to spend time fixing something that works
4. They are using version 11+ that should be much safer to upgrade than earlier versions, but they are still in the mindset of 1 or 2 above
There have been huge improvements not only in the language itself, but also performance and memory use. They could save money if they upgrade, but in some cases this is acceptable because they can make more money by spending time on a new feature, than an upgrade.
In my last 3 workplaces, they usually tried to use the latest LTS versions. But to be honest, some of the services were in maintenance mode and we didn't get enough benefits to upgrade, so we were sometimes falling behind. Today we have a mix of v17 and v21. Anyone can upgrade anytime they want but noone cares about a service that you seldom work with. I feel kind of bad for that, but not enough to bother. I focus mainly on the services that I work with daily, and make sure they are using the latest versions
You missed the most obvious reason to not upgrade: there is no good reason to do it.
> There have been huge improvements not only in the language itself, but also performance and memory use.
That's debatable, and even if we blindly assume that then it's debatable whether the upgrade justifies the gains.
More often than not, it doesn't.
This is not debatable. It’s a factual truth. Every single actual performance review concludes that modern Java vastly out performs the decade old Java 8 runtime.
For an example here is a quote from Hazelcast when comparing performance of modern Java on data heavy workloads [0]:
> JDK 8 is an antiquated runtime. The default Parallel collector enters huge Full GC pauses and the G1, although having less frequent Full GCs, is stuck in an old version that uses just one thread to perform it, resulting in even longer pauses. Even on a moderate heap of 12 GB, the pauses were exceeding 20 seconds for Parallel and a full minute for G1. The ConcurrentMarkSweep collector is strictly worse than G1 in all scenarios, and its failure mode are multi-minute Full GC pauses.
This is from 2020 and the gap has only gotten wider.
[0] https://hazelcast.com/blog/performance-of-modern-java-on-dat...
I don't think you even bothered to read the sources you're quoting, and you're just trying to make baseless assertions.
The very first question on JetBrain's survey is "Which versions of Java do you regularly use?", and 50% answered Java 8 with around 2% mentioning Java 7 and 1% answering Java 6. On top of that, Java11 alone comprised around 38%.
And you're talking about Java21? It doesn't even register in the survey at all.
The data there clearly shows that the ecosystem has as many users running a modern version. Which directly counters your assertion that everyone is just running 8.
I don't think people realize Java8 was until very recently the dominant java version in production software, and currently close to 90% of all java projects still run on java11 and earlier.
Edit: after checking New Relic's 2024 report on the java ecosystem, it sounds like java11 and earlier is now at slightly over 60%, with java17 being used in around 35% of the projects.
But, yes, with static imports, you can just write "println" like that and have it work.
did you know that every function in a python script is actually an attribute of that module (which is basically a class). so my point is: who cares.
You still need to know what a main class is, so that you can reference it in your build.gradle file.
But it's useful for little one-off scripts, where you just go `$ java foo.java` from the command line.
(My guess: It is.)
> So you don't need to worry about functions floating around in a global namespace soup.
Because having classes floating around in a global namespace soup is fundamentally different and should give no worries to anyone. Yet this was argument made in earnest back when arguments about Java's strengths and weaknesses were much more popular.
Basically, imagine a `class Temporary4738 {` and `}` written above and below the .java file's content, that's roughly how it will behave.
It not having a fixed name is deliberate, so if you decide to build a bigger system you won't use this mechanism in a hard to maintain way, and also it needed a good semantic model for "top-level" variables/fields.
But with this implicit class model, top-level definitions are just fields of the class.
The same strategy is also followed by C# with their top-level statements. And yes, it's syntactic sugar.
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals...
Welcome to the last 10+ years of Java. They're trying to play catch-up to other languages that made fundamentally different and better choices, making Java more and more complicated in the process. They are so deeply entrenched in the enterprise back end space that programmers put up with it, nay, even feel grateful for it. People who are stuck using Java for the rest of their careers are happy to see it grow to accommodate 21st century programming techniques, even if it means that it becomes so complicated and crufty that no beginner will touch it ever again.
eg want to run code for 6 months at a go managing hundreds of gigs of data, tens of thousands of threads, at high load, with sustained gigs a second of garbage generation? the jvm will just silently tick away doing just that while being nearly bulletproof. As much as I love ruby and python, you ain't doing that with them.
With hot code loading, introspection, etc. All the stuff that makes developing super-robust long-lived systems way easier.
And the flip side of the clunky language is your code from 20 years ago still works.
Scala mainstreamed a bunch of concepts that java was slow to adopt, but the end result was java only took the good ideas and didn't take the bad ideas.
10+ years ago I considered myself proficient at C++. It made sense, I didn't mind the pointers, and while the std library still felt clunky, it was fine. But I tabled these skills, and they indeed rusted a bit, but surely I could bring them out when needed again, right?
Smart pointers with multiple variants, judicious use of macros, rampant use of double colons to ensure proper namespace resolution (which IMHO makes the code an absolute eyesore), to name a few. I won't argue these changes aren't necessary, but it isn't pretty.
Packages still exist.
It’s just not necessary to add an additional level of namespacing.
Statics never were some pure OOP anyway.
But what does this code even mean..? Isn't Java's whole simplifying model that everything lives in "Objects"? This seems to break that fundamental paradigm and makes the language more complicated. If you needed something like global functions then in vanilla Java as I remember you'd stick it into static final Objects that acts as a namespace of sorts. So you don't need to worry about functions floating around in a global namespace soup.
If you're gunna just have free floating functions in your file.. then why not just cut to the chase and have a
floating in your file..? (I mean... you don't have REPL so maybe that wouldn't be too meaningful...)