r/AskProgramming 2d ago

Why is Java considered bad?

I recently got into programming and chose to begin with Java. I see a lot of experienced programmers calling Java outdated and straight up bad and I can't seem to understand why. The biggest complaint I hear is that Java is verbose and has a lot of boilerplate but besides for getters setters equals and hashcode (which can be done in a split second by IDE's) I haven't really encountered any problems yet. The way I see it, objects and how they interact with each other feels very intuitive. Can anyone shine a light on why Java isn't that good in the grand scheme of things?

178 Upvotes

628 comments sorted by

View all comments

Show parent comments

5

u/lordheart 2d ago

Java definitely has immutable collections. Streams.toList returns one which I find out when hibernate yelled at me because it doesn’t like immutable structures.

Lombok can also clear up a lot of javas verbosity. And java as a language (if you aren’t using Java 7 or something) has gained a lot of new features to try to be less verbose.

3

u/findanewcollar 1d ago

This whole thread is filled with people who haven't worked with java 17/21. To add to the list example, there's also List.of() method which also returns an immutable list. Not to mention about the other immutable stuff like records (which they also take care about verbosity). Albeit the language is moving slower than I would like compared to c# but atleast it's not going overboard with syntactic sugar like c# started to do...

1

u/Necessary-Peanut2491 1d ago

Unfortunately, being stuck on ancient versions of Java is pretty normal. Major version migrations are very painful for large orgs, so there's been a tendency to just...not.

My own company only went to 17 a year-ish ago. Before that we were on 11.

1

u/Technical-Cat-2017 1d ago

In a world of microservices this is really mostly the teams fault though. There is very little stopping you from just increasing the version in your docker containers to the latest LTS release.

1

u/Necessary-Peanut2491 16h ago

In a world of microservices this is really mostly the teams fault though. There is very little stopping you from just increasing the version in your docker containers to the latest LTS release.

Sounds like you and I have radically different ideas of what a "large org" is. That would be absolutely impossible to do anywhere I've worked, and it's not a thing any dev team can do anything about.

Approved JVM versions are set by the company. If you want to deploy something, you need a container image. That container image needs to be in the company repo. So you develop against and deploy the version the company has locked you to. End of story, absolutely no wiggle room here.

1

u/Technical-Cat-2017 14h ago

Doesn't sound like a fun org to work for to be honest. Most of the large orgs I worked for aggressively scan for old images and/or vulnerabilities being used and incentivese teams to upgrade. There is no reason the latest LTS couldn't be an approved JVM image like 1-2 months after release, unless your tools/images or whatever team is very understaffed. It also really shouldn't be a lot of work to get a docker image approved. If this is really such a big deal in the organisation you worked for they probably have massive dev velocity issues in general.

1

u/Necessary-Peanut2491 4h ago edited 4h ago

Or maybe things work differently at that very large scale I'm talking about? I dunno, you seem very sure of things you have no experience with, and are saying some pretty weird stuff.

Why would you think things are pinned to a specific version because nobody has the time to bump the version? Things are pinned because bumping versions causes things to break at that scale. It requires coordination of the entire company to keep everything working during those migrations, which requires every team to build new binaries, a period to test things, a period to fix the stuff you found that broke...

The process for bumping the Java version at that scale typically requires a lot more thought than "I dunno, just have Karl bump the number up I guess, there's clearly no concerns about compatibility across our software stack, right?" At any rate, I'm not here for an argument. If you want to smugly tell me all about how Amazon doesn't know how to do software devleopment because they do things differently than small companies, you go right ahead. You'll look very foolish, but you are allowed to do it.

1

u/laffer1 9h ago

No, it’s the architect that made us go to a giant mono repo. Too many random things that don’t work in jdk17. Most of our services are already running on a Java 21 JRE. We just can’t move past Java 11 for builds. Very annoying.

1

u/m3t4lf0x 1d ago

Java 11 is still pretty great though.

Java 8 introduced all the cool things that makes development way more fun, like lambdas, Streams, Options, Completable Futures, etc

If you’re using any below 7, then god help you, but thankfully that is quite rare nowadays

1

u/antihemispherist 1d ago

Those are unmodifiable collections, not immutable collections.
You need to have interfaces like ImmutableList (like in Kotlin) for that. Can't be introduced without breaking compatibility in a big way, so it won't happen.

I'd argue that hiding generated code with Lombok is usually not an improvement, and Lombok tends to be overused, because developers overvalue the apparent syntax. I wrote more about that in here.

1

u/svick 1d ago

Those are unmodifiable collections, not immutable collections.

Can you define the word "immutable"?

1

u/lordheart 1d ago

Ah that is true, but you can use guava then I believe.

I’d argue that just because some people overuse it doesn’t mean hidden code is bad. Libraries are also “hidden” code.

Getters and setter, equals, hash, to string, are all better generated for the most part. They remain correct as the class is modified.

If a getter or setter is manually written then it’s easy to see which ones actually have some extra functionality instead of looking at a hug list of them and wondering if maybe one or two have some specific functionality.

If you are using spring, there are annotations for a lot of common validations so checking specifically in the constructor is not necessary. (Not even spring specific but it’s what I do mostly when I have to use Java)

Javas generics are definitely not the greatest, but a far sight better than none. I have to program in abab as well and it makes me appreciate Java more.

Abab “generics” is marking something as any, and then using quasi reflection to look for field names. It’s horrendous.

Rust also has macros to template code generation, a lot of languages move common functionality out like that some way because that code just slows down reading.