Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Java is over two decades old and one of the most widely used languages in the world. It has absolutely stood the test of time. While it does has its pain points its nowhere near as terrible as C++ and (in my opinion) is improving with new versions, and honestly, I think its a joy to program in though that might not be a "cool" thing to say. Whereas C++ is a chore to program in.

That's my opinion, maybe I'm just too used to high level programming to be "good" in C++ but my experience is C++ breaks the "principle of least astonishment" every single time I use it. For example, a simple operation like clearing a stringstream is... not straightforward.

...Or maybe I'm just not smart enough.



Well, there's not a lot of room for problems to crop up when all one can do is define classes :)

Still, here's a few for you: the design of Cloneable is considered to be a mistake, as are exception specifications. These have real negative consequences. File IO was laughably bad and completely unintuitive needing several classes for the simplest of tasks (perhaps this was fixed more recently, but funny you should mention streams).

Resource management was quite tricky to get right before try-with-resources and it still is if one wants performance. Memory leaks and resource leaks are still possible. Boxing and unboxing. The particularly weak type-erased generics.

Java's saving grace is that it's a very programmer-friendly language. No matter how much one screws up, the worst that's probably gonna happen is a null pointer exception with a nicely formatted stack trace attached. The tooling is top class. All of this means that anybody with a pulse can program in Java and get a mostly working program. It won't be a joy to use, unless one is particularly impressed by classes, methods, interfaces in abundance, class hierarchies and factories.

C++ is not like that. If one doesn't use the safer modern idioms and makes a mistake it will crash (if lucky),or act in weird ways or corrupt something. Sometimes there is no way to avoid dangerous code.

There is no nice stack trace, you have to work for it. Probably have to stare at assembly and work with a fully featured but thoroughly painful to use command line debugger that's twice as old as Java.

But it's powerful and really fast. It lets one design creatively, because it supports more abstraction possibilities. And it's not owned by any corporation, it's an international standard that runs on most platforms.

I understand why people use Java. I use C++ because it's not just a tool that gets the job done, but also a way to challenge myself to make something that requires attention and skill. If I want to, it's me and the machine without framewerks, factories, fancy IDEs, dependency injection, package managers and virtual machines.


Like I said, Java has its pain points but Java's pain points are both being drastically improved on with time (java.time anyone?) and was never as bad (in my opinion) as C++. My main point is that Java has stood the test of time without becoming as bad as C++.

I'm not impressed by "classes, methods, interfaces in abundance, class hierarchies and factories." I find Java a joy to program in because I can just Get Shit Done™ and things do what I expect them to do.

In my old age I just want to get shit done, challenging myself is no longer very appealing. That's a personal preference though. There was a time that wasn't the case.

Obviously managed code is not for every application but its good enough for most. I am eternally grateful for C++ programmers for the applications where C++ (or other lower level languages) are needed because I wouldn't want to be doing that. I think C++ programmers, as a group, are so used to C++ idiosyncrasies that they don't see them as idiosyncrasies. That goes for any group though.

For what its worth my first language was C++ but C++ always "astonished" me.

(I've never had a problem with boxing and unboxing. Java has had autoboxing for a really long time so those days of manual boxing/unboxing are ancient history)


File IO got a rework with java.nio.

"Several classes" Are you taking about input/output streams, not file I/O?


> Java is over two decades old and one of the most widely used languages in the world.

Half the age of C++ (and it's ancestor C which is it largely compatible with).

> It has absolutely stood the test of time.

Sure, it's held up really well. It takes advantage of the fact that baking in GC, memory safety, and platform independence sweeps a lot of C++'s nastiness under the rug. Of course, those choices are also what generally makes Java unsuitable for many of the things you can do in C++.

Even so, Java has certainly acquired it's share of cruft. Primitives, type erasure, checked exceptions, Uri.equals() hitting the network (!), nested classes, covariant arrays, arrays and lists being different and arrays getting all the nice syntax, etc.


Agreed but in my opinion the cruft in Java is not nearly as bad as the cruft in C++. That's a personal opinion though, I'm mostly a Java programmer in my day job so that may cloud my perception of the language because I'm so used to it. I've never fought with Java like I have with C++.


It's URL::equals that hits the network, not URI::equals; the latter is a lot more sane. And even URL::equals often won't hit the network, because Java caches DNS lookups forever.

I realise that i am not exactly disproving your point about cruft here.


Ha, I couldn't remember if it was URI or URL and I was too lazy to look. :-/


Checked exceptions is definitely cruft. Java is also has the advantage of trying to be less things than c++. It's not a systems language and it's hardly even a desktop applications language anymore. Java has the same niches as ruby and python more than c++.


I'm seeing a few people in this thread mention checked exceptions being cruft. I haven't heard this before and was wondering about the reasoning.

Why are checked exceptions cruft?


Because in practice they lead to exceptions not being handled properly with a lot of boilerplate try catches. If you can't do anything sensible with an exception (like retry a couple of times) then they shouldn't be caught. The other alternative is chaining throws on function definitions up the call stack.

Most new libraries don't use checked exceptions. They were a good idea in theory but not in practice.


What do you think of languages like Rust, Go, or Haskell which return errors as part of the return type? That's somewhat akin to having all exceptions be checked.


This is the exact opposite of checked exceptions, it returns an error you don have to handle at all.

It turns me off go and Haskell altogether because they are languages suitable to applications. I think it's going to lead to a lot of apps in the wild ignoring errors.

Rust is a bit different because it's a systems language, it makes sense there.


I don't think it's the exact opposite at all. It forces you to "catch" the exception, but doesn't force you to do anything with it, the same as a checked exception.

Like in Go I can do:

    f, err := os.Open("foo.bar")
    
I am then free to ignore err or do something with it, but the type system forces me to at least acknowledge that it exists. It's the "compiler forces you to acknowledge the possibility of an error" that makes them pretty similar to checked exceptions in my opinion.


Yeah it's similar in that sense, but checked exceptions force you to acknowledge every type of exception that can be thrown, or one generic one. If you can't handle it then they force you to list every type of exception that can be thrown all they way up the chain.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: