[HN Gopher] Rating 26 years of Java changes
___________________________________________________________________
Rating 26 years of Java changes
Author : PaulHoule
Score : 113 points
Date : 2025-10-11 18:29 UTC (4 hours ago)
(HTM) web link (neilmadden.blog)
(TXT) w3m dump (neilmadden.blog)
| JanisErdmanis wrote:
| > if you wanted to store an integer in a collection, you had to
| manually convert to and from the primitive int type and the
| Integer "boxed" class
|
| I have never worked with Java. What is this? Why would one want
| to have a class for an Integer?
| morcus wrote:
| It's because the collection types (and generics) don't support
| primitives, only objects. So you been to stuff the primitives
| into objects to use them with a lot of the standard library.
| JanisErdmanis wrote:
| That doesn't sound very pleasant.
| dcminter wrote:
| Well, it was annoying until autoboxing came in.
| // Before autoboxing list.add(new Integer(42));
| // After autoboxing list.add(42);
|
| Mostly it's a non-issue now. If you're desperately
| cycle/memory constrained you're likely not using Java
| anyway.
| marginalia_nu wrote:
| You can get pretty good performance out of Java these
| days, so long as you know to avoid stuff like boxed
| primitives and the streams api, as they generally have
| god-awful memory locality, and generally don't vectorize
| well.
| dcminter wrote:
| Yeah, I know there are even oddballs using it for HFT and
| the like - I like Java a lot, but even I find that a bit
| peculiar.
|
| Edit: actually, if someone here _is_ using it for
| something like that I 'd love to hear the rationale...?
| Arwill wrote:
| There are libraries, like fastutil, that provide
| collections for primitive types.
| coldtea wrote:
| Either the same of this feature or always hiding the boxing
| (e.g. a Python int is actually a wrapper object as well,
| with some optimizations for some cases like interning) is
| the case in almost all languages.
| JanisErdmanis wrote:
| I personally use Julia, which does not have such boxing
| issues. Rust, C, C++, and Fortran also avoid boxing like
| this. Perhaps Go is also free from such boxing? Python
| does it, that's true.
| dcminter wrote:
| One of the more amusing bugs I had to figure out resulted
| from the fact that some of the autoboxed values get cached,
| resulting in peculiar behaviour when someone managed to
| reflectively change the boxed primitive value...
|
| i.e. something like: Integer x = 42
| highlyQuestionableCode(x); println(x); // "24" WAT?
|
| I'm a fan of JEP-500...
|
| https://openjdk.org/jeps/500
| raspasov wrote:
| I think your intuition is correct: you probably don't.
|
| 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 wrote:
| Primitive variables in Java, such as `int`, `boolean`, and
| `double`, store their actual values directly in memory. When
| they are local variables inside a method, this memory is
| typically allocated on the thread's stack. These primitives do
| not have the structure or overhead of an object, including the
| object header used by the Garbage Collector (GC) to manage
| heap-allocated objects.
|
| 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.
| wpollock wrote:
| Aside from this, having such a class provides a convenient
| place to hold all the int utility functions, and the same for
| the other primitive types.
| iceboundrock wrote:
| It appears that most of the good changes are imported from C#.
| sjrd wrote:
| Or Scala. Or Kotlin. Or any of the other languages that had
| most of these features years if not decades before Java. ;)
| marginalia_nu wrote:
| Yeah that's very much an explicit design philosophy of Java,
| dating way back. Let other languages experiment, and adapt
| what proves useful.
|
| 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.
| agos wrote:
| What other language made them think checked exceptions were
| a good idea?
| coldtea wrote:
| Most of original C# was imported from Java, so there's that...
| dkarl wrote:
| Definitely underrates the impact of annotations. I'm personally
| not a fan of the way annotations are used to implicitly wire
| together applications, but I have to admit the impact. Maybe 5/10
| is fair in light of the wide range of positive and extremely
| negative ways annotations can be used.
|
| 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.
| dhosek wrote:
| I used to joke that the direction spring was heading was that
| you'd have an application be a boilerplate main method with a
| dozen lines of annotations. Then I actually encountered this in
| the wild: we had an app that sent updates from db2 to rabbitmq,
| and the application literally was just configuration via
| annotations and no actual Java code other than the usual spring
| main method.
| bdangubic wrote:
| this is _exactly_ why spring succeeded. I need to run a
| scheduled job, @EnableScheduling then @Scheduled(cron =
| "xxxxxx") - done. I need XYZ, @EnableXYZ the @XYZ... sh*t
| just works...
| vbezhenar wrote:
| Yeah, it works until it isn't. And they good luck debugging
| it. I'd prefer simple obvious linear code calling some
| functions over this declarative magic any day.
| 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.
| bdangubic wrote:
| never had any issues debugging as I am never debugging
| the scheduler (that works :) ) but my own code.
|
| and what exactly is "cronService"? you write in each
| service or copy/paste each time you need it?
| alex_smart wrote:
| You can write your own libraries?
|
| My goodness. What a question!
| skeletal88 wrote:
| Then you need to deploy it on multiple nodes and neex to
| make sure it only runs once for each run of the cron, etc.
| bdangubic wrote:
| while not working on out of the box clustered this is
| trivial issue to address
| taftster wrote:
| And then I realize I need to change that schedule. And
| would like to do it without recompiling my code. Oh, and I
| need to allow for environment specific scheduling, weekdays
| on one system, weekends on others. And I need other
| dependencies that are environment specific.
|
| I much prefer Spring's XML configuration from the old days.
| Yeah, XML sucks and all that. But still, with XML, the
| configuration is completely external from the application
| and I can manage it from /etc style layouts. Hard coding
| and compiling in dependency injection via annotations or
| other such behaviors into the class directly has caused me
| grief over the long term pretty much every time.
| nunobrito wrote:
| The only real-world usage I see for annotations are in
| GSON (the @Expose) and JUnit with @Test.
|
| Never really came across with any other real cases where
| it solves a pressing issue as you mention. Most times is
| far more convenient to do things outside the compiled
| code.
| 9dev wrote:
| Is that strictly bad, though? Being able to run an enterprise
| service by setting configuration values declaratively, and
| get all the guarantees of a well-tested framework, seems like
| a pretty good thing.
|
| 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.
| SkiFire13 wrote:
| I think the general adversity against this specialized
| configurations is that they often tend to be fairly
| limited/rigid in what they can do, and if you want to
| customize anything you have to rewrite the whole thing.
| They effectively lock you into one black box of doing
| things, and getting out of it can be very painful.
| tormeh wrote:
| It's seriously puzzling. I just don't get how it's possible to
| look at what so many others have done better, and somehow
| design something worse. For what reason? Consistency with the
| rest of the language, possibly? But is that really so
| important. Do they just not want to tackle certain parts of the
| compiler?
| dcminter wrote:
| Some of the weirder choices have been the result of a desire
| to avoid making breaking changes to JVM bytecode.
|
| 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)
|
| Edit: I should add that it's now on a fixed 6-monthly release
| cycle which IMO works _much_ better.
| rzwitserloot wrote:
| OpenJDK redesigns massive swaths of the compiler every other
| month.
|
| The true explanation, at least the way OpenJDK says it, is
| that designing language features is more complex than a
| casual glancer can fathom, and there's 30 years of "Java is
| in the top 5 most used languages on the planet, probably #1
| especially if focussing on stuff that was meant to be
| supported for a long time" to think about.
|
| From personal experience, essentially every single last "Just
| do X to add (some lang feature) to java; languages A and B do
| it and it works great!" would have been bad for java. Usually
| because it would cause a 'cultural split' - where you can
| tell some highly used library in the ecosystem was clearly
| designed before the feature's introduction.
|
| Even if you introduce a new feature in a way that doesn't
| break existing code, it's still going to cause
| maintainability headaches if you've cornered the pillars of
| the ecosystem into total rewrites if they want to remain up
| to date with the language. Because they will (or somebody
| will write an alternative that will) and you've _still_
| 'python 2 v python 3'd the language and split the baby in the
| half.
|
| For what its worth, I think the OpenJDK team doesn't take
| this seriously enough, and a number of recently introduced
| features have been deployed too hastily without thinking this
| through. For example, `LocalDate`, which has 'this should be
| a record' written all over it, _is not a record_. Or how the
| securitymanager is being ditched without replacements for
| what it is most commonly used for here in the 2020s. (To be
| clear: Ditching it is a good idea, but having no in-process
| replacement for "let me stop attempts to access files and
| shut down the JVM, not for security purposes but simply for
| 'plan B' style fallback purposes" - that's a bit
| regrettable).
|
| I'm nitpicking on those points because on the whole OpenJDK
| is doing a far better job than most languages on trying to
| keep its ecosystem and sizable existing codebase on board
| _without_ resorting to the crutch of: "Well, users of this
| language, get to work refactoring everything or embrace
| obsoletion".
| vbezhenar wrote:
| I don't really feel that Java uses proven features.
|
| 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.
| rzwitserloot wrote:
| > For example they used checked exceptions.
|
| Those are from java 1.0 and thus don't appear to be relevant
| to the part of the discussion I think this part of the thread
| is about (namely: "Why doesn't java crib well designed
| features from other languages?").
|
| > Java went with checked exceptions and nowadays they are
| almost universally ignored by developers.
|
| They aren't.
|
| Note that other languages invented for example 'Either' which
| is a different take on the same principle, namely: Explicit
| mention of all somewhat expectable alternative exit
| conditions + enforcing callers to deal with them, though also
| offering a relatively easy way to just throw that
| responsibility up the call chain.
|
| The general tenet (lets lift plausible alternate exit
| conditions into the type system) is being done left and
| right.
| JavierFlores09 wrote:
| Stuart Marks and Nicolai Parlog recently had a discussion
| about checked exceptions in the Java channel [0]. In short,
| while they mentioned that there are certainly some things to
| improve about checked exceptions, like the confusing
| hierarchy as well as the boilerplate-y way of handling them,
| they're not necessarily a failed concept. I do hope they get
| to work on them in the near future.
|
| 0: https://www.youtube.com/watch?v=lnfnF7otEnk
| vbezhenar wrote:
| They are absolutely failed concept in Java. Every first
| popular library uses unchecked exceptions, including famous
| Spring. Java streams API does not support checked
| exceptions. Even Java standard library nowadays includes
| "UncheckedIOException". Kotlin, Scala: both languages grown
| from JVM, threw away do not support checked exceptions.
| torginus wrote:
| which is kinda horrifying - it means the framework designers
| didn't find the language powerful enough to express app logic,
| and hotglued their own custom arbitrary behavior on top of it.
|
| Clear language code should be endeavor to be
| readable/understandable when printed on a sheet of paper by
| anyone, acceptable code should be understandable by anyone who
| knows a bit about the technologies and has some IDE support.
|
| Garbage code is what you have when the code in question is only
| understandable when you actually run it, as it uses arbitrary
| framework logic to wire things together based on metadata on
| the fly.
| Groxx wrote:
| people have been gluing other languages on top of languages
| practically forever - it's a DSL.
|
| no single language is ideally suited for every situation,
| it's not inherently a sign of failure that someone makes a
| DSL.
|
| and since annotations are part of the language, this is still
| all "the language is flexible enough to build the framework
| [despite being wildly different than normal code]" so I don't
| think it even supports that part.
| rzwitserloot wrote:
| That's not how the OpenJDK sees things. They tend to think that
| the features they deliver are at best mildly informed by other
| languages. Not out of some sense of hubris, but out of a sense
| of pragmatics: Simply copy and pasting features from other
| languages into java - _that_ would produce a frankenstein.
|
| For example, java is somewhat unique in having lambda syntax
| where the lambda *must* be compile-time interpretable as some
| sort of 'functional type' (a functional type being any
| interface that defines precisely 1 unimplemented method). The
| vast, vast majority of languages out there, including scala
| which runs on the JVM, instead create a type hierarchy that
| describe lambdas as functions, and _may_ (in the case of scala
| for example) compile-time automatically 'box'/'cast' any
| expression of some functional type to a functional interface
| type that matches.
|
| Java's approach is, in other words, unique (as far as I know).
|
| There was an alternate proposal available at the time that
| would have done things more like other languages does them,
| completely worked out with proof of concept builds readily
| available (the 'BGGA proposal'). The JVM would autogenerate
| types such as `java.lang.function.Function2<A, B, R>`
| (representing a function that takes 2 arguments, first of type
| A second of type B, and returns a value of type R), would then
| treat e.g. the expression:
|
| `(String a, List<Integer> b) -> 2.0;`
|
| As a `Function2<String, List<Integer>, Double>`, and would also
| 'auto-box' this if needed, e.g. if passing that as the sole
| argument to a function:
|
| ``` void foo(MyOperation o) {}
|
| interface MyOperation { Double whatever(String arg1,
| List<Integer> arg2); } ```
|
| This proposal was seriously considered but rejected.
|
| The core problem with your comment is this:
|
| Define the terms "polished" and "elegant". It sounds so simple,
| but language features are trying to dance to quite a few
| extremely different tunes, and one person's 'elegance' is
| another person's 'frankensteinian monster'.
|
| The same mostly goes for your terms "beauty" and "charm", but,
| if I may take a wild stab in the dark and assume that most
| folks have a very rough meeting of the minds as to whatever
| might be a "charming" language: I know of no mainstream long-
| term popular languages that qualify for those terms. And I
| think that's _inherent_. You can 't be a mainstream language
| unless your language is extremely stable. When you're not just
| writing some cool new toy stuff in language X - you're writing
| production code that lots of euros and eyeballs are involved
| in, and there's real dependence on that software continuing to
| run, then you __must__ have stability or it becomes extremely
| pricey to actually maintain it.
|
| With stability comes the handcuffs: You need to use the
| 'deprecation' hammer extremely sparingly, essentially never.
| And that has downstream effects: You can't really test new
| features either. So far I have not seen a language that truly
| flourishes on the crutches of some `from future import ...`
| system. That makes some sense: Either the entire ecosystem
| adopts the future feature and then breaking _that_ brings the
| same headaches, or folks don't use these features / only for
| toy stuff, and you don't get nearly the same amount of
| experience from its deployment.
|
| Said differently: If java is a frankenstein, so is Javascript,
| C#, Python, Ruby, Scala, and so on. They have to be.
|
| I'd love to see a language whose core design principles are
| 100% focussed on preventing specifically that. Some sort of
| extreme take on versioning of a language itself that we haven't
| seen before. I don't really know what it looks like, but I
| can't recall any language that put in the kind of effort I'd
| want to see here. This is just a tiny sliver of what it'd take:
|
| * The language itself is versioned, and all previous versions
| continue to be part of the lang spec and continue to be
| maintained by future compilers. At least for a long time, if
| not forever.
|
| * ALL sources files MUST start with an indication about which
| version of the language itself they use.
|
| * The core libraries are also versioned, and separately. Newer
| versions are written against old language versions, or can be
| used by source on old language versions.
|
| * The system's compilers and tools are fundamentally operating
| on a 'project' level granularity. You can't compile individual
| source files. Or if you can, it's because the spec explains how
| a temporary nameless project is implied by such an act.
|
| * All versions ship with a migrator tool, which automatically
| 'updates' sources written for lang ver X to lang ver X+1,
| automatically applying anything that has a near-zero chance of
| causing issues, and guiding the programmer to explicitly fixing
| all deprecated usages of things where an automated update is
| not available.
|
| * The language inherently supports 'facades'; a way for a
| library at version Y to expose the API it had at version X (X
| is older than Y), but using the data structures of Y, thus
| allowing interop between 2 codebases that both use this
| library, one at version X and one at version Y.
|
| That language might manage the otherwise impossible job of
| being 'elegant', 'simple', 'mainstream', 'suitable for serious
| projects', and 'actually good'.
| nine_k wrote:
| Absolutely. It seems that the author never touched Spring, for
| instance, or a dependency-injection framework of any kind.
| Annotations allow to do things in a _completely_ different way,
| removing tons of boilerplate.
|
| I'd give annotations 9/10 at least.
|
| (And I lost the interest in the rest of the article, given such
| a level of familiarity with the subject matter.)
| Groxx wrote:
| and that's before even touching on the compilation steps they
| can add, which are a _pluggable_ codegen and macro system
| that is also integrated into IDEs, which is completely
| missing from almost every other language.
| jayd16 wrote:
| The ratings are really all over the place. Jshell is a 6/10?
| Supermancho wrote:
| Can someone explain why developers like var?
| pgwhalen wrote:
| It reduces (often repetitive) visual noise in code, which can
| make it more readable. I wouldn't recommend using it in all
| cases, but it's a good tool to have.
| Traubenfuchs wrote:
| It's a harmful code smell: It often obfuscates the type,
| forcing you to actively check for the type and should not be
| used.
| Supermancho wrote:
| This is what it looks like to me. If you wanted to do this,
| why not use a scripting language where you can use this kind
| of practice everywhere? In Java, I don't expect to have to
| look up the return type of something to discover a variable
| type. Graciously, I can see how you can save rewriting the
| Type declaration when it's a function return you want to
| mutate.
|
| Generally, you save some keystrokes to let other people (or
| future you) figure it out when reading. It seems like bad
| practice altogether for non trivial projects.
| guax wrote:
| Modern IDEs will show you the type of anything at all
| times. I do not understand your point unless you're doing
| raw text editing of Java source.
|
| Those keystrokes are not just saved on writing, they make
| the whole code more legible and easier to mentally parse.
| When reading I don't care if the variable is a specific
| type, you're mostly looking whats being done to it, knowing
| the type becomes important later and, again, the IDE solves
| that for you.
| newAccount2025 wrote:
| Your IDE can do that?
| a57721 wrote:
| It is used for things like "Foo x = new Foo()" where the type
| is obvious.
| tofflos wrote:
| It's terse and it lines up the variable names.
| flykespice wrote:
| It's another thing they adopted from Kotlin, since Kotlin is
| supposed to be a "better java". Now Java is retroactively
| adopting Kotlin freatures.
| speed_spread wrote:
| Kotlin didn't invent type inference, it's a feature from ML.
| speed_spread wrote:
| It's called type inference and it's the way things should be.
| You get the same types but you don't have to spell them out
| everywhere. Java doesn't even go all the way, check OCaml to
| see full program inference.
| miningape wrote:
| OCaml's type inference is truly amazing, makes it such a
| delight to write statically typed code - reading it on the
| other hand...
|
| 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.
| Supermancho wrote:
| Annotations would be a substitute for writing the return
| type. Extra code for a shortcut seems like the worst
| solution.
| N70Phone wrote:
| Previously (or if you simply don't use var), a lot of java code
| takes the form of 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.
| guax wrote:
| To me var is what makes modern java somewhat readable and more
| bearable. It was always a joke that it takes too long to write
| anything in java because of the excessive syntax repetitions
| and formalities. To me that joke is heavily based on a reality
| that modern Java is tackling with this quality of life
| features.
| whartung wrote:
| I get the attraction to var, but I, personally, don't use it,
| as I feel it makes the code harder to read.
|
| Simply, I like (mind, I'm 25 year Java guy so this is all
| routine to me) to know the types of the variables, the types
| of what things are returning. var x = func();
|
| doesn't tell me anything.
|
| And, yes, I appreciate all comments about verbosity and code
| clutter and FactoryProxyBuilderImpl, etc. But, for me, not
| having it there makes the code harder for me to follow. Makes
| an IDE more of a necessity.
|
| Java code is already hard enough to follow when everything is
| a maze of empty interfaces, but "no code", that can only be
| tracked through in a debugger when everything is wired up.
|
| Maybe if I used it more, I'd like it better, but so far, when
| coming back to code I've written, I like things being more
| explicit than not.
| nunobrito wrote:
| Yes, well expressed. For that case using var is not a wise
| approach.
|
| It does help when writing: var x = new
| MyClass();
|
| Because then you avoid repetition. Anyways, I don't ever
| use "var" to keep the code compatible with Java-8 style
| programming and easier on the eyes for the same reasons you
| mention.
| CrimsonRain wrote:
| 1. Just because you can use var in a place, doesn't mean
| you should. Use it where the type would be obvious when
| reading code like var myPotato = new
| PotatoBuilder.build();
|
| not like var myFood = buyFood();
|
| where buyFood has Potato as return type.
|
| 2. Even if you don't follow 1, IDEs can show you the type
| like var Potato (in different font/color)
| myFood = buyFood();
| mi_lk wrote:
| I have the opposite feeling. var makes it easier to write but
| harder to read/review. Without var you know the exact type of
| a variable without going through some functions for example
| haunter wrote:
| I'm sorry, please don't hate me (I'm tired and don't have
| anything better to do) https://files.catbox.moe/ge4el3.png
| rvitorper wrote:
| Dude, this is awesome
| alex_smart wrote:
| Why so much hate for modules? They seem to be almost
| universally disliked by everyone on this thread and I don't
| understand why.
| harladsinsteden wrote:
| I don't know what to make of this list...
|
| 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.
| tofflos wrote:
| I will make any excuse to use Streams but understand the
| negativity. They are difficult to debug and I feel the support
| for parallelism complicated, and in some cases even crippled,
| the API for many common use cases.
| nunobrito wrote:
| I'm that author. It has been more than a decade and still won't
| use streams nor lambdas. Makes the code too difficult to write
| and debug for me.
|
| Really prefer to have more lines of code and understanding very
| clearly what each one is doing, than convoluting too many
| instructions on a single line.
| Arwill wrote:
| -10 for modules is fair, only 4 for lambdas is not. My
| programming style changed after using lambdas in Java, even when
| using a different programming language later that doesn't have
| lambdas as such.
| marginalia_nu wrote:
| I think the author is sleeping on Java assertions.
|
| 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.
| rwmj wrote:
| I'm quite surprised that he said asserts are not found in
| production code. Is that really so? I rarely write Java, but in
| C code we use asserts (in production code) all the time. It's
| not uncommon for functions to contain 2 or 3 asserts.
| dcminter wrote:
| I very rarely see assertions in "real" Java code; I think the
| author is right - in fact the place I see them the most often
| is in unit tests where they've been used _by mistake_ in
| place of an assertion library 's methods!
|
| I don't know why they're not more popular.
| nunobrito wrote:
| Good conversation, I had no idea what assertions are beyond
| JUnit.
| marginalia_nu wrote:
| If you're only doing like CRUD endpoints, they may be less
| useful, but that's hardly the extent of Java production code.
| I certainly use asserts in production code quite a lot in
| Java, though the use biases toward more low level functions,
| rarely in high level application logic.
| brap wrote:
| What are the pros of making this a keyword vs just a standard
| function?
| zylepe wrote:
| I haven't used markdown in javadoc yet but this seems like at
| least 3/10? I often want to put paragraphs or bulleted lists in
| javadoc and find myself wanting to use markdown syntax for
| readability in the code but need to switch to less readable html
| tags for tooling to render it properly.
| ronyeh wrote:
| I hate using html in comments.
|
| Markdown in javadoc is at least 7/10 for me. Improves comment
| readability for humans while allowing formatted javadocs.
| rsynnott wrote:
| I feel this is overly harsh on Collections. You have to take into
| account just how awful that which it replaced was.
|
| > 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.
| wpollock wrote:
| >Again, it is hard to overstate just _how_ bad the previous
| version [of Java time] is.
|
| The original Java Time classes were likely a last-minute
| addition to Java. They were obviously a direct copy of C
| language time.h. It feels as if the Java team had a
| conversation like this: "Darn, we ship Java 1.0 in a month but
| we forgot to include any time functions!" "Oh no! We must do
| something!" "I know, let's just port C time.h!"
| zkmon wrote:
| Applets (Java 1.1 - that's where I started),
|
| 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)
| foolfoolz wrote:
| the biggest things to change java have been type inference,
| lambdas, records, streams (functional ops on collections), and
| pattern matching. these are all must-have features for any modern
| programming language. at this point any language without these
| features will feel old and legacy. it's impressive java was able
| to add them all on decades after release, but you do feel it
| sometimes
| newAccount2025 wrote:
| For my part, returning to Java a couple years back after 15+
| years away, streams + var/val were my favorite discoveries.
| sedro wrote:
| Autoboxing's evil twin, auto-unboxing should knock the score down
| a few points. Integer a = null; int b = 42;
| if (a == b) {} // throws NullPointerException
| dcminter wrote:
| Or my favourite... Short w = 42; Short x
| = 42; out.println(w == x); // true Short y = 1042;
| Short z = 1042; out.println(y == z); // false
| prein wrote:
| Once, after we had an application go live, we started getting
| reports after a few hours that new users were unable to log
| in.
|
| It turns out, somewhere in the auth path, a dev had used `==`
| to verify a user's ID, which worked for Longs under (I
| believe) 128, so any users with an ID bigger than that were
| unable to log in due to the comparison failing.
| tombert wrote:
| Interesting; I actually have grown pretty fond of NIO.
|
| 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 :)
| simonklee wrote:
| java.util.Date and java.util.Calendar are the two packages I
| remember struggling with as a new programmer. Which I guess is
| solved with java.time after Java 8.
| b_e_n_t_o_n wrote:
| I haven't written much Java but I am learning Kotlin and I really
| appreciate the language and the whole JVM ecosystem. Yeah yeah,
| Gradle is complicated but it's waaaaay easier to figure out than
| my adventures with Cmake, and when I read Java code there is a
| certain _comfort_ I feel that I don 't get with other languages,
| even ones I'm experienced with like Go. Java feels a bit like a
| stranger I've known my whole life, same with Kotlin. Perhaps
| despite all its flaws, there is a certain intrinsic quality to
| Java that has helped make it so popular.
| MarkMarine wrote:
| I'm sure there are better ways to do streams on the JVM, scala
| being a great example, but however imperfect the implementation
| is streams are such a net positive I can't imagine the language
| without them. I pine for the streams API when I write go.
| AbuAssar wrote:
| so java 22, 23, 24 are all released in 2024?
| dcminter wrote:
| No, it's a 6 month release cadence. You might be confusing the
| initial release with a point release which are less regular.
| Edit: oh, my bad, I see the article author had the wrong year
| for 24. 22 was March 2024 23 was
| September 2024 24 was March 2025 25 was September
| 2025
|
| This is much better than the old "release train" system where
| e.g Java 5 and Java 6 were released in Sept 2004 and Nov 2006
| respectively!
| linuxhansl wrote:
| Didn't Java 1.3 (Sun's JDK) introduce the JIT? I remember talking
| to colleagues about what a joke Java performance was (we were
| working in C++ then). And then with Java 1.3 that started to
| change.
|
| (Today, even though I still C++, C, along with Java, I'll
| challenge anyone who claims that Java is slower then C++.)
| brap wrote:
| Wow I can't believe try with resources is so old! I've been
| working with Java for years and only learned this exists
| recently, I thought it must be relatively new. 14 years!
| travisgriggs wrote:
| Ah Java. The language I never got to love. I came of coding age
| during the "camps" era of object oriented stuff: Eiffel,
| Smalltalk, CLOS, C++, etc. Java, from 95ish to oh 98ish, was like
| a giant backdraft. Completely sucked the air out of the room for
| everything else.
|
| Does anyone remember the full page ads in WSJ for programming
| language, that no on quite yet knew what it really was? So my
| formative impressions of Java on were emotional/irrational,
| enforced by comments like:
|
| "Of Course Java will Work, there's not a damn new thing in it" --
| James gosling, but I've always suspected this might be urban
| legend
|
| "Java, all the elegance of C++ syntax with all the speed of
| Smalltalk" - Kent Beck or Jan Steinman
|
| "20 years from now, we will still be talking about Java. Not
| because of its contributions to computer programming, but rather
| as a demonstration of how to market a language" -- ??
|
| I can code some in Java today (because, hey, GPT and friends!! :)
| ), but have elected to use Kotlin and have been moderately happy
| with that.
|
| One thing that would be interesting about this list, is to break
| down the changes that changed/evolved the actual computation
| model that a programmer uses with it, vs syntactic sugar and
| library refinements. "Languages" with heavy footprints like this,
| are often just as much about their run time libraries and
| frameworks, as they are the actual methodology of how you compute
| results.
| rr808 wrote:
| Java is great, Spring ruined the platform.
| taspeotis wrote:
| Which release did they add the URL class that checks for equality
| by connecting to the internet? 10/10
| pixelmonkey wrote:
| A cool thing about Doug Lea's java.util.concurrent (received a
| 10/10 rating here) is that its design also inspired Python's
| concurrent.futures package. This is explicitly acknowledged in
| PEP 3148[1] (under "Rationale"), a PEP that dates back to 2009.
|
| [1]: https://peps.python.org/pep-3148/
| nunobrito wrote:
| Fully agree with most votings but 3/10 text blocks?!
|
| That has got to be one of the most useful recent features. :-)
|
| The pleasure of just copying and paste text in plain ASCII that
| looks as intended rather than a huge encoded mess of "\r\n"+
| concatenations.
|
| But ok, I'm just an ASCII art fan. ^_^
| w10-1 wrote:
| It's nice to review the features, but the history of Java isn't
| really about features or even programmer popularity.
|
| (1) It was the first disruptive enterprise business model. They
| aimed to make everyone a Java programmer with free access (to
| reduce the cost of labor), but then charge for enterprise (and
| embedded and browser) VM's and containers. They did this to
| undercut the well-entrenched Microsoft and IBM. (IBM followed
| suit immediately by dumping their high-end IDE and supporting the
| free Eclipse. This destroyed competition from Borland and other
| IDE makers tying their own libraries and programming models.)
|
| (2) As an interpreted language, Java became viable only with good
| JIT's. Borland's was the first (in JDK 1.1.7), but soon Urs
| Holzle, a UCSB professor, created the HotSpot compiler that has
| seeded generations of performance gains. The VM and JIT made it
| possible to navigate the many generations of hardware delivering
| and orders-of-magnitude improvements and putting software in
| every product. Decoupling hardware and software reduced the
| vertical integration that was killing customers (which also
| adversely affected Sun Microsystems).
|
| btw, Urs Holzle went on to become Google employee #8 and was
| responsible for Google using massively parallel off-the-shelf
| hardware in its data centers. He made Google dreams possible.
___________________________________________________________________
(page generated 2025-10-11 23:00 UTC)