It's stable to the point of boring, and there's no shortage of people who know the language and can work with it, it's got best in class tooling, decades worth of libraries almost all very mature. Most of the language's issues are from legacy code bases coded in a style that isn't really relevant to a greenfield project.
The ecosystem has (at long last) standardized on JSpecify (https://jspecify.dev) for nullability annotations. JSpecify allows you to annotate a package or module with `@NullMarked` and your IDE and build (via ErrorProne+NullAway, typically) will check for null safety.
If you develop a library in Java and use it from Kotlin, the built-in Kotlin null-safety will recognize the JSpecify annotations on the library.
It's a panic in Go, not an exception. In practice that's usually a whole process crash. You can catch panics and kinda use them like exceptions, but it's not conventional.
Can I trust code I’ve written myself with no guarantees from the language? Maybe. Can I trust code written by dozens of other developers (and/or agents) working on the same project over multiple years? Definitely not.
Can you explain what the issue is with nullability here? Is the concern that someone's code returns null in normal circumstances but doesn't document that well, so you don't check if null? Cause if it's an error situation, one way or another some exception has to be thrown.
Everyone has to deal with other code that might not even be from the same org. The "check it in CI" answer isn't an excuse either. You're bolting on so much extra crap that way.
I just don't see why nullability is a problem in the first place.
Most engineers do not have the ability to impose rules by fiat on all of their coworkers. It seems like you're misunderstanding the nature of working on a codebase as an IC when other developers contribute to it. If all of my coworkers don't want a lint rule I propose, I don't get to add it. If all of my other coworkers want to write code in a certain way and approve each other's MRs with code written in that way, I don't get to veto it.
Most engineers don't get to decide to use a language either. Usually someone with the clout to pick a language has the clout to set style requirements too.
They do get to decide which jobs they take. And the languages involved are one of the easiest filters. A lot easier than checking whether the code a company actually writes is any good.
Theoretically you don’t need to write AbstractFactoryProvider in Java, but looking at languages mentioned in job offers, I have a pretty good idea of which of them have a high probability of working with such code and which do not, even if all of them say they have the best code ever.
I don't disagree, but that sounds more like a response to the person asking "what's the argument for picking Java?" than one to the someone who finds "Have you tried not returning null or constructing incomplete objects?" and "Why don't you have any coding standards?" to be poor takes.
If someone's asking "why Java" or is saying nulls make it a hard no, then you'd assume that they have a choice in the first place, which generally means they also have some ability to set coding standards at the same time that they're choosing a language.
Scala technically allows you to use nulls or throw exceptions pretty much wherever (necessary for Java compatibility), but it's not an issue because people simply don't outside of super niche situations (generally some low-level thing, or a shim). Similar to `unsafe` in Rust. Or casts in all sorts of languages.
> If someone's asking "why Java" or is saying nulls make it a hard no, then you'd assume that they have a choice in the first place, which generally means they also have some ability to set coding standards at the same time that they're choosing a language.
I don't understand that logic. I sometimes ask people to explain why they think a certain policy should be implemented by the government after they state their support for it, but I don't have the ability to set government policy. I have trouble imagining you genuinely assume that any time someone asks you why something should be the way you say that you think they have the ability to change it if you convince them.
Of course you assume that; if you're talking about what a policy should be, then you work in a hypothetical world where the policy can be chosen. You don't say "but what about some other minor detail! That would require an additional policy choice, and we can't change related policies."
Like if I think my business should open an hour earlier, and you say "but the employees won't be there yet so who will open the doors!" obviously the solution is to also change the work schedule. When you have closely related policies, generally the same person/people are empowered to make both changes.
I admit I haven't worked in Java for years, but no project I've seen at my current company (the only one I've worked at since agents have been a useful thing) is anywhere close to removing all dependencies. From what I've seen, people want to spend tokens on new things, not things that are already known to exist. Even if you can reinvent the wheel, it's not something that an employer is going to be particularly happy to subsidize.
It is really not a big deal nowadays, the problem of the same scale as having index out of bounds error (no language has good defence against this, yet it is not a catastrophe).
That's expected (the index out of bound). You have an array, and maybe it grows, you read a number from input, you don't check it against the size of the array because you want to torture the language, use it to get the element at that index and... I'm sure that there is a surprisingly number of different designs of what it should happen and a number of designed ways to ensure that it doesn't happen. But a runtime error is expected.
yes, so are the NPEs - both are runtime errors indicating a bug in the code. NPE was a major source of irritation 20 years ago, but what many people do not know is that debugging NPEs in Java is easier now - they carry more information about the source. And the culture has evolved.
Unlike C it is trivial to catch a NullPointerException and confine the crash to the unit of work. And unlike C you are not talking about insanely dangerous pointers, you're just talking about an NPE.
I'll admit it's a hassle when something wasn't initialized properly and then you get a null pointer exception at some unrelated code much later. It's not always easy to debug. Catastrophic? No!
There are a lot of third party tools that can check for null safety and a lot of work is being done to make Java's initialization safer but also a little more flexible, there is
and there are all sorts of practical answers. Nulls in Java are low on my list of annoyances, way behind front end programmers who pepper my CSS files with "!important" because they don't know about precedence (though maybe they think my .clazz.clazz.clazz selector is brain dead!)
I’m not sure how long it will take, but please - can we stop saying that annotations like @IHopeThisWontBeNull is a toy for kids and, having so many years of incidents caused by those and having LLMs to write and fix the code, we can rely on language and compiler already?
You're drawing a distinction that doesn't matter in practice. If you encounter a NullPointerException incident then you either didn't annotate your code or you didn't run the tooling. (In fact before even running your CI suite, any serious IDE will tell you immediately that you've mishandled null somewhere.)
I get that some people feel like it ought to be built-in to the language rather than a separate tool... but people's personal feelings are irrelevant to the lived experience of my day-to-day work, where worrying about null is truly a thing of the past.
It's stable to the point of boring, and there's no shortage of people who know the language and can work with it, it's got best in class tooling, decades worth of libraries almost all very mature. Most of the language's issues are from legacy code bases coded in a style that isn't really relevant to a greenfield project.