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.
Null-restricted types are on the roadmap. See: https://openjdk.org/jeps/8303099
Use NullAway and it basically makes the problem go away. Our application won't build if it detects a potential NPE.
I get it why this seems like a less drastic change, but this saddens me. Kotlin solves more issues with the type system (smart casts, reified types, immutability by default), without sacrificing readability. Unless I can see a solution in Java that makes dealing with NPEs as easier for lazy developers as ignoring them, I don't consider it a solved issue.
You deserve the strawman award of the year.
NullAway and JSpecify encourage making as many types non-nullable as possible, thus they can actually also advice about removing redundant null checks. Nullable types become the painful exception that visibly spreads through the codebase, which discourages writing code that relies on null.
Optional doesn't enter the picture at all. NullAway kills their usecase within ones own code. They are anyway only recommend as return types to force others to check for an emoty case, but I think Optional will become fully optional when the Java platform gets nullable types on its own.
Google Error Prone is a code linting tool that's very useful in its own right, and NullAway is just another plugin.
https://github.com/uber-go/nilaway
Not exactly the same solution as JSpecify, since it doesn't rely on annotations, but it's also more ergonomic.
I'm not comparing this to "null-restricted types", since that's a draft JEP that hasn't made it even into a preview feature. Go also had multiple proposals for explicit nilability in types, and while they probably have less prospect of ever seeing the light of day compared to Project Valhalla, as things currently stand, Go is in the same position as Java: They are both extremely prone to NEPs out-of-the-box and they both have external tooling that can help you avoid them.
Java null checkers have more comprehensive coverage potential compared to Go, but Go is the more ergonomic one here. You don't need a single extra annotation on your code.
This is kinda bad practice. Go and Rust panics are similar, they aren't exceptions that you can safely recover from. Say there's a panic in the middle of modifying some global state like a database connection. Hence complaints about the net/http recover like https://github.com/golang/go/issues/25245 . But I guess they decided it's worse to let servers crash from trivial mistakes.
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.
For concrete example, it took me a long time to find a job last year due to only fully remote being viable since my wife's autoimmune condition means I'd be risking her health by commuting, and nowadays most places seem to either expect hybrid if you live near an office (I'm within the geographic limits of NYC despite being nowhere near Manhattan), restrict by time zone (there were quite a few jobs I was interested in where they only would accept remote with Pacific or Mountain Time), or have onerous travel requirements (multiple opportunities I interviewed for didn't work out because they expected me to fly to the west coast every couple of months, which between the time there and jet lag would mean I'm not productive close to a quarter of the time).
I was in a fortunate position to be able to hold out for a while and ended up finding a fully job with my preferred language after around eight months, but I had already come up with a timeline for when I should start relaxing certain constraints if it went on longer. Programming language was literally the first constraint that I was going to drop if it lasted a few more months because prioritizing my wife's health is non-negotiable, and I'd rather work in a language I don't like as much on something that I don't feel is actively making the world a worse place than work in my favorite language on adtech or at some cryptocurrency startup. It's not clear to me why it would be a problem for me to care about using my non-favorite programming language well if I happened to be employed to write it.
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.
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.
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.
> When should one use Java on projects?
> One shouldn't consider Java because it lets you use null.
> That's easily solvable by just not using null.
> But you can't just do that. People will use it.
> You can just do that. Tell them not to.
Like I'm not seeing the issue. This is like saying you can't use Rust because people will use `unsafe` because it lets them do C programmer things, and then claiming it is simply impossible to tell them not to do that (and set tool policies to flag anyone attempting to).
In the real world, if you're in a position to even ask "why use Java for a new project?" then you are presumably also in a position to have "don't use nulls" be a satisfying answer to "what about nulls?" If someone is asked what technology to use for a project in the first place, they are almost certainly also asked about how it will be used. The hypothetical here is not "do you have coding standards" but "are you a decision maker," and when the original question is "when should one decide to do X," you have to accept as a premise that you are placing yourself in the role of a decision maker in the first place.
I'm not seeing how you can seriously claim that the amount of unsafe used in Rust over the past 11 years is anywhere close to the amount of null used in Java for the past three decades. The vast majority of Rust projects don't have any unsafe used directly in them. I have trouble believing that the fraction of Java projects that don't ever touch null is anywhere close to as high.
> In the real world, if you're in a position to even ask "why use Java for a new project?" then you are presumably also in a position to have "don't use nulls" be a satisfying answer to "what about nulls?
You keep framing questions as something people only ever ask if they happen to have the power to make decisions, and that still makes no sense to me.
> The hypothetical here is not "do you have coding standards"
That's almost the exact question I responded to initially! You responded to me responding to the question "Why don't you have any coding standards?". I feel like you're trying to argue against me as if I commented several levels above in the thread than I actually did, and then getting confused by me not accepting that premise.
I'm not framing it as a question one only asks if they happen to have the power to actually decide to use it; obviously a curious student might want to know why large successful companies continue to use the JVM even for new projects. I'm saying that the answer can be given from the perspective of someone who does have that power, and that the question is really "if I can choose a language, why would I choose Java." That doesn't imply that the person asking actually has that power, but it prevents silly answers that are addressed by "don't do that."
I just don't see why nullability is a problem in the first place.
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.
Unfortunately, no, they don't. Not after your application has been running for a while; newer JVMs arbitrarily decide you don't need the stack trace anymore, and all you see in your logs is "NullPointerException" (unless you still have the logs from several weeks ago, just after the last JVM restart, which might still have the full stack trace). Older JVMs were better, since they always had the full stack trace; debugging NPEs was easier with them.
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
https://openjdk.org/jeps/8303099
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!)
Otherwise, yeah, you're still in for a world of pain.