It hasn't worked out in terms of delivering perfect language design, but it has worked out in the sense that Java has an almost absurd degree of backward compatibility. There are libraries that have had more breaking changes this year than the Java programming language has had in the last 17 releases.
So many of these features were adopted after they were proven in other languages. You would expect that since Java took such a slow and conservative approach, it would end up with extremely polished and elegant designs, but things like streams ended up inferior to previous developments instead of being the culmination. Really disappointing. Java is now a Frankenstein's monster with exactly as much beauty and charm.
cronService.schedule("xxx", this::refresh);
This isn't any harder than annotation. But you can ctrl+click on schedule implementation and below easily. You can put breakpoint and whatnot.Yes, it’s weird how that’s still Java, but using standard components and only using code as glue where it’s absolutely necessary seems very similar to other engineering disciplines to me.
Also there was a long period when changes were very lumpy - it could be multiple years for a feature to make it into the release, and anything that might screw up other features got a lot of pushback. Then other conventions/tools emerged that reduced the urgency (e.g. the Lombok stuff)
For example they used checked exceptions. Those definitely do not seem like proven feature. C++ has unchecked exceptions. Almost every other popular language has unchecked exceptions. Java went with checked exceptions and nowadays they are almost universally ignored by developers. I'd say that's a total failure.
Streams another good example. Making functional API for collections is pretty trivial. But they decided to design streams for some kind of very easy parallelisation. This led to extremely complicated implementation, absurdly complicated. And I've yet to encounter a single use-case for this feature. So for very rare feature they complicated the design immensely.
Modules... LoL.
We will see how green threads will work. Most languages adopt much simpler async/await approach. Very few languages implement green threads.
But I think that's easily solved by adding type annotations for the return type of methods - annotating almost anything else is mostly just clutter imo.
BeanFactoryBuilder builder = new BeanFactoryBuilder(...);
This is just straight up a duplicate. With generics, generic parameters can be left out on one side but the class itself is still duplicated.Very strange reasoning and even stranger results: Streams 1/10?! Lambdas (maybe the biggest enhancement ever) a mere 4/10?!
Sorry, but this is just bogus.
I really like the feature, and it's really one of the features I feel Java got right.
The syntax is very expressive, and they can easily be made to generate meaningful exceptions when they fail.
It's also neat that it gives the language a canonical way of adding invariant checks that can be removed in production but run in tests or during testing or debugging (with -da vs -ea).
You could achieve similar things with if statements, and likely get similar performance characteristics eventually out of C2, but this way it would be harder to distinguish business logic from invariant checking. You'd also likely end up with different authors implementing their own toggles for these pseudo-assertions.
> Java Time: Much better than what came before, but I have barely had to use much of this API at all, so I’m not in a position to really judge how good this is.
Again, it is hard to overstate just _how_ bad the previous version is.
Though honestly I still just use joda time.
Servlets (Together with MS ASP, JSP/Servlets have fuelled the e-commerce websites)
I think Java dominated the scene mostly because of its enterprise features (Java EE) and the supporting frameworks (Spring etc) and applications (Tomcat, Websphere, Weblogic etc) and support from Open source (Apache, IBM)
Integer a = null;
int b = 42;
if (a == b) {} // throws NullPointerException
I will acknowledge that the interface is a bit weird, but I feel like despite that it has consistently been a "Just Works" tool for me. I get decent performance, the API is well documented, and since so many of my coworkers have historically been bad at it and used regular Java IO, it has felt like a superpower for me since it makes it comparatively easy to write performant code.
Granted, I think a part of me is always comparing it to writing raw epoll stuff in C, so maybe it's just better in comparison :)
JanisErdmanis•1h ago
I have never worked with Java. What is this? Why would one want to have a class for an Integer?
morcus•1h ago
JanisErdmanis•51m ago
dcminter•42m ago
marginalia_nu•28m ago
dcminter•22m ago
Edit: actually, if someone here is using it for something like that I'd love to hear the rationale...?
Arwill•37m ago
coldtea•31m ago
dcminter•47m ago
i.e. something like:
I'm a fan of JEP-500...https://openjdk.org/jeps/500
raspasov•52m ago
That’s also very likely changing. Lookup “project Valhalla”. It’s still a work in progress but the high level goal is to have immutable values that “code like a class, work like an int”.
PS When I say “changing”: it’s being added. Java tries hard to maintain backward compatibility for most things (which is great).
iceboundrock•50m ago
If a primitive value must be treated as an object (e.g., when stored in a Java Collection like ArrayList or when passed to a method that requires an object), Java uses a process called `boxing` to wrap the primitive value into an instance of its corresponding Wrapper class (e.g., Integer, Boolean, Double). These Wrapper objects are allocated on the heap and do possess the necessary object header, making them subject to the GC's management.