Hacker News new | ask | show | jobs
by stingraycharles 768 days ago
Eh, it’s not the most sexy language, because across all dimensions, there are more scary languages.

C++ is much more scary than Java in a “shoot yourself in the foot” kind of way.

INTERCAL is much more scary than Java in a “this is impossible to understand code” kind of way.

Haskell is much more scary than Java in a “this language has FP constructs” kind of way.

So why is Java scary?

6 comments

Java is uncool, and to some people there's nothing scarier than not looking cool.

Java is great. Solid ecosystem, solid performance, decent memory safety story, tons of production experience, etc.

My problem with Java is that it is excessively object-oriented. I understand they've toned that aspect of it way down, but when I worked in Java between 2003-2009 it was gospel and it was preachy. But wow did I grow to hate it over time. I entirely quit programming for a couple of years, in fact. Then I discovered Python and I couldn't believe how easy it made everything, so I came back.
To be honest, that over-architecture everything stuff came from even earlier with C++, that many people forget.

Java was just a valid target to many programs that were previously written in C++, and some of that mindset stuck.

I would argue though, that today’s java is not excessively OOP, and can be written in an elegant hybrid of OOP and FP, whichever suits the given subproblem best. (It literally has algebraic datatypes and pattern matching now).

Not really, if you compare the STL with the java standard library, the STL is much more category-theory / traits-oriented, and has a lot of "free" functions, where the java standard library is OOP madness.
Dependency management and build systems suck though :D
Gradle can become a mess when people want to show their smartness with the build system, don't allow them (even better if one just avoids Gradle entirely).

Maven works fine, it has so much history that most problems you encounter have been solved. It's also pluggable so you can extend to your heart's desires (but you shouldn't, same as Gradle when people try to be too smart with plugins it's time to tell them to stop).

Could it be better? Of course! But just as the rest of Java: it gets the job done, and it's absolutely fine after you deal with some idiosyncrasies. Every programming language environment has their own unique set of idiosyncrasies to deal with.

Java is a workhorse, it's not sexy, it's not pretty but will get you pretty far in most production environments.

This is annoyingly true, although maven is nice enough to work with. Certainly beats its alternatives handily, being declarative and such. Not nearly as annoying as Ant and Ivy, and at least IMO, the less one needs to think about Gradle, the better.

But of course, maven could also be a lot better.

Why?

Maven and Gradle both have a learning curve, but IMO they're better than what exists for C/C++ (which really don't have _any_ standard dependency management).

I fully agree that this problem also exists in C/C++. I was comparing it to the likes of Go or Rust.
Oh, sure. Go and Rust both have great dependency management.
I would like to add though that there is a big difference between a language-specific build tool that pretty much can’t build anything else and will bleed out at the first sight of another language in the project, and something like Gradle which is a fully generic build system capable of, say, a whole android build.

Of course a specialist will be “more elegant” at solving it’s intended problem, but that’s often not all we need.

Yes, because meta programming in macros, makefiles, and embedding binary libraries or using git submodules is soo much more elegant.. yikes.
I don't mind Java so much as the types of code people tend to write with it. No one needs a FooReactorFactoryFactory when. There is only a single FooReactor which is always chosen. I've recently learned that it's possible to write such abominations in C++, which is equally bad.

And don't get me started on dependency injection systems like Guice. @Inject just means I have no way of knowing the type of an object or how it is initialized without sifting through the entire code base looking for an @Provides. And even then I can never be sure.

I have two gripes with how Java is today:

1) A lot of enterprise devs think all problems are best solved in Java, and refuse to acknowledge anything else (looking at the IBMers in the room) 2) Spring Boot takes what you don't like about Guice and cranks it up ten levels. It's so common in the industry that it might as well be adopted as a javax package now.

> I've recently learned that it's possible to write such abominations in C++, which is equally bad

It’s not only possible, that’s where all this stuff originates from. Gang of 4 has examples in C++ for a reason.

> @Inject just means I have no way of knowing the type of an object or how it is initialized without sifting through the entire code base looking for an @Provides.

If you're using interfaces correctly with strong contracts, the concrete implementation shouldn't matter.

This falls apart very quickly if your implementations don't match the contract.

Guice can be quite pleasant (though confusing at first) since it makes it easy to test your code and easily swap out implementations of classes, e.g. for dev vs prod.

Guice is honestly the worst DI container I’ve ever used. It has no life cycle support and you have to hack around all of its features. Id take any of the popular ones over it. Spring/Avaje/CDI. Most likely Avaje since it most easily supports compile time injection.
I enjoy working in Java. I would probably enjoy C# just as much. Life is too short to spend it debugging segfaults.
My only gripe with C# is async/await.
It's not too bad, but they made some questionable choices for sure (Task vs. ValueTask, bad ConfigureAwait default for Windows forms).
I just don't want to live in that world of colored functions and the amount of sync -> async changes I'll have to review from the bottom up every time IO gets stuffed into the middle of somewhere.
> So why is Java scary?

There's a lot of Internet trolls that like to bash it and influencers e.g. on Youtube that like to use it to look hip.

It's less about the facts and more about it being the biggest target they can hit.

Coincidentally their religion is called Javascript and according to them there can only be 1 Java.

As far as I am aware, Java is the only major programming language (other than JavaScript, which is also the only worse major language) that was not organically adopted by programmers.

JavaScript was forced on the world by being the language of the browser, but Java was foisted on the world by Sun Microsystems in a massive marketing campaign.

And then Java was bought by the kind of person who isn't a programmer but needs to make some kind of sensible choice at some company, along with the kind of person who needs to teach freshman programming according to the latest fad.

Don't forget the millions Sun spent literally ADVERTISING Java.

For 2-3 years (2003-4?) every other tech-related book that was published had something to do with Java. I remember going into a Barnes and Noble once, back in that era, and walking down an aisle that felt like it was 30 feet long and four shelves high of just Java books. It was all marketing.

After a decade people suddenly woke up and realized "oh, Java sucks".

Then the smart kids moved on, but the rest of the world is now stuck with Java, and there will always be those kinds of people around who aren't programmers but who need to make what they think is some kind of sensible choice.

Of course, the Java community has also realized what a pile of ** Java was, so now they've added all sorts of lambdas and better syntax and whatnot, but it's band-aids on top of a fundamental misconception, which is that object-oriented programming is the best way to model software engineering problems.

> JavaScript was forced on the world by being the language of the browser, but Java was foisted on the world by Sun Microsystems in a massive marketing campaign. [...] Don't forget the millions Sun spent literally ADVERTISING Java.

Also, don't ever forget that Java was the other "language of the browser". Netscape came bundled with a Java Runtime Environment, back when everyone used Netscape. You were supposed to write your web application as Java applets, with JavaScript being the bridge between the static HTML world and the dynamic Java applet world (which also explains why its name was changed from LiveScript to JavaScript).

At least back in the day (might be fixed now) with type covariant mutable arrays.

That is array of cat is a subtype of array of animal. And a function Foo taking an array of animals and appending a dog is legal. Because array of cat is a subtype of array of animal, you can pass an array of cats to foo and append a dog. I believe this causes a runtime type exception, in a type-checked language without using any dangerous casts.

I kind of assume modern java has addressed this somehow, I would love to hear how.

No, this is still a thing (and a performance issue) in both Java and C#. Covariance has a substantial penalty on array writes (20-40% depending on the benchmark).

I'm not that familiar with Java, but in C#, the only ways to avoid the penalty are either making the class of the array type sealed (so the runtime knows that you can't put any subtype into it) or using a construct like this if you work with someone else's type which you can't make sealed:

  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  private static T access<T>(T[] arr, int index) {
      ref T tableRef = ref MemoryMarshal.GetArrayDataReference(arr);
      return Unsafe.Add(ref tableRef, index);
  }
(this doesn't bounds check either, and hard-crashes on an empty array so you need to guard it appropriately)
This does not hard-crash on an empty array[0] but can still cause bad UB and eventually crash should it point past allocated memory page or to other random data (spec allows to have a byref that would point to the last element of array if it were one element longer, but such dereference out of bounds is still UB).

Covariance is unfortunate choice of arrays of T where T is class and is widely considered a mistake today. When you pass Memory<T> or Span<T>, there are no covariance checks involved as they disallow it.

It is also less of an issue in .NET in general because quite often T is a struct instead, which does not have covariance in the OOP meaning of the word (old-style int[] to uint[] casts are just reinterprets, they are frowned upon luckily and few codebases use them).

[0] https://sharplab.io/#v2:EYLgtghglgdgNAFxAJwK4wD4AEBMBGAWACgs...

This is solved through generics. List<T> will be invariant.
I can’t remember the last time I wrote a raw array. There’s absolutely no reason for it.
"Absolutely no reason" is wrong, "almost certainly no reason for most programs" is more accurate. You'll need arrays of you're writing buffers, various types of collections (B-trees, hashtables), etc.
Well, while I do agree with you (I would even add performance-sensitive code to your list. Something like int[] applied at the correct places can do a lot), if we want to be absolutely nitpicky one can just use ByteBuffers over arrays for pretty much everything.
Of course if you want to be pedantic. But no one is writing these. 99% of all code is going to use collections from the standard library.
I don’t fear Java as much as I fear its acolytes.
Kind of a strange comment for Java which doesn't really have a quasi-religious fanbase of e. g. Rust or Python.
A comment from an alternative reality where code patterns, crazy code generation frameworks, and crazy systems entirely based on dependency injection do not exist...
Oracle had employees called Java Evangelists for a while but I think that was more than a decade ago. You never know when somebody gets their stereotypes though.

My memory is hazy but I think there may have been more of a cult of Java when Sun was in charge of things. They knew now to inspire a following.

> Oracle had employees called Java Evangelists

Well, that's just marketing department.

> I think there may have been more of a cult of Java when Sun was in charge of things.

I wouldn't call it a "cult", just normal technology hype. Yeah, it was there in the late 90s, but since at least 2010s, Java is a boring enterprise platform without much hype.

Does Java have acolytes?

It might have before, like, 2005 when it became the default “intro to programming” language. And it might get some now that Python has taken that job. But for a while it was the “minimum requirements: fulfilled” of programming languages. There’s a lot to be said for fulfilling minimum requirements but that doesn’t tend to inspire evangelism.

It is a perfectly fine language in as much as I saw, that must be why it was selected for the sad fate of being many overwhelmed students’ first language.

Yeah, since the ‘90s, and still does in this thread. They’re usually going around insisting you ignore that your lying eyes can consistently spot Java programs by their incredible memory bloat and poor performance, and that actually it has great performance (in some synthetic benchmarks).

I do think they’ve gained a little credibility now that we’ve inexplicably decided Electron is a serious platform and not an April Fool’s joke.

We just want to write code for money in peace.