18

Question: Is there an implementation of the Elvis operator scheduled for any future Java release? Or is there any Library that brings it to Java?

I have read that

it was proposed for Java SE 7 but didn't make it into that release

http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html

I know Java 8 allows this

String name = computer.flatMap(Computer::getSoundcard)
                          .flatMap(Soundcard::getUSB)
                          .map(USB::getVersion)
                          .orElse("UNKNOWN");

but I it's s bit too much for my taste. SO if anyone could point me out any project / library that would bring the Groovy like/C# like syntax to Java for Null Checks, would be greatly appreciated.

Edit: By Elvis operator I mean this:

String version = computer?.getSoundcard()?.getUSB()?.getVersion();

or similar

Holger
  • 285,553
  • 42
  • 434
  • 765
user73362
  • 353
  • 3
  • 8
  • 4
    [Optional](http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html) is part of Java 8 but I don't know about the elvis operator – ooxi Oct 23 '14 at 13:23
  • 5
    Um, `?.` isn't what groovy calls the elvis operator. That would be `?:`. – mabi Oct 23 '14 at 13:27
  • 2
    "Safe navigation" operator. The Elvis operator is a shortened ternary where the result is either the item being operated on or an alternative if it's null/falsey. – Dave Newton Oct 23 '14 at 13:36
  • thanks for clarifying, should I change the Title of the Question then? – user73362 Oct 23 '14 at 13:42
  • The Elvis operator was discussed here: http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000047.html – lbalazscs May 05 '15 at 23:43

2 Answers2

16

No. There are no current or future plans to reconsider the null-safe operators in Java.

Brian Goetz
  • 90,105
  • 23
  • 150
  • 161
  • 1
    Since Oct 23 '14 till today (June 2016) have there been any thoughts about implementing it now? – Srujan Barai Jun 25 '16 at 09:54
  • 2
    @SrujanBarai Nope. C# syntax wins again. – Zaaier Jul 08 '16 at 17:57
  • 2
    See also: [Why were Null-Safe Operators (e.g. “Elvis operator”) rejected as part of Java's “Project Coin”?](https://softwareengineering.stackexchange.com/q/359414/81973) – Thunderforge Oct 19 '17 at 18:35
  • 1
    Well then. You simply can't get a more authoritative response than this answer. – scottb Apr 09 '21 at 02:13
  • 1
    As a both Groovy and Java developer, I feel like Java should provide such a important feature, because almost 10% code people write for null check only...either checking null in if condition or try...catch. but in groovy it works just with ? (safe navigation operator) in a same line, without any extra code. – Nitin Dhomse Jan 31 '22 at 07:38
  • Even Groovy truth, closures I really missed Groovy magic in Java even you are upgrading Java to version 17 now. – Nitin Dhomse Jan 31 '22 at 07:43
3

A long time ago, there was a function

public static Foo getFoo(Bar bar) {
  return bar.getFoo();
}

And people just couldn't agree what should happen if bar was null.

First of all, there would be people who would claim that violating the intent of the function should be penalized with a checked exception.

public static Foo getFoo(Bar bar) throws FooNotFoundException {
  if (bar == null) throw new FooNotFoundException();
  return bar.getFoo();
}

The caller of the function would then be forced to take this scenario in account. It would have to catch the exception or rethrow it. It would be so forceful that it would annoy people, and soon they would argue that this shouldn't be a checked exception, but a runtime exception, to make it less forceful.

public static Foo getFoo(Bar bar) {
  if (bar == null) throw new FooNotFoundException();
  return bar.getFoo();
}

Some would claim that there would be no point in throwing an exception, since java would already throw an exception anyway: a Nullpointer exception.

Those who would fear unexpected exceptions, would just make their code more rebust and would add null-checks at the start of their functions, which would simply return null.

public static Foo getFoo(Bar bar) {
  if (bar == null) return null;
  return bar.getFoo();
}

Soon people would be arguing if it would be ok to return empty lists, or whether those empty lists should actually be null values as well. "Surely, you don't want to check nullability before each and every iteration, do you?" would the other side argue. And soon, they would be creating all kind of constructs to avoid nullability entirely.

public static Foo getFoo(Bar bar) {
  if (bar == null) return Foo.Empty;
  return bar.getFoo();
}

Each approach would have a wide range of consequences. And those consequences would make it difficult to combine different approaches. Those consequences would result in coding rules where each individual rule would be connected to the next rule. The way they supported each other would give the impression that each and every rule was undisputable. And finally coding rules would become like religions with reasoning which only made sense inside the scope of the full ruleset.

Depending on your choice of ruleset you would have difficulties using certain frameworks. In the end, the empty-list with unchecked-exceptions religion became dominant. This religion can be summarized as follows:

  • you should avoid returning null values.
  • if a list is empty, you return it as is.
  • if you iterate a list, you never have to check for null.
  • a method should never throw a checked exception
  • checked exceptions should be wrapped in runtime exceptions.
  • strings shouldn't ever be null, instead they should be "".

And apparently this religion got so strong that it managed to influence the framework and language specification.

  • compiler optimizations for empty lists
  • an Optional class
  • value types

Some external libraries and editors would actually try to re-unite the different teams by providing annotations (@Null and @NotNull). The IDE would just mark all violations for you. A simple but effective solution. Nevertheless, the JDK never included its own @Null or @NotNull, instead each library had to ship their own.

And taking all of this in account, right now, it is very unlikely that there will ever be an elvis operator in java. If you want to code in java, you better forget about null.

Or to put it in the words of Tony Hoare (the inventor of null):

I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.

Personally, I think this absolutely makes no sense, given the fact that every decent programming language has a null. Some even have multiple ones to indicate different kinds of nullabilities. After all, even in mathematics there are undefined values.

Anyway, if you don't have an elvis operator, you can still

Foo foo = bar == null ? null : bar.getFoo();

And this just fits perfectly in the spirit of java. After all, in 2021 java is a very explicit language.

bvdb
  • 22,839
  • 10
  • 110
  • 123
  • `Foo foo = bar == null ? null : bar.getFoo();` is more or less ok, but the example from the question is not that nice anymore, and a real pain to write over and over again: `Version version = computer == null ? null : computer.getSoundcard() == null ? null computer.getSoundcard().getUSB() == null ? null computer.getSoundcard().getUSB().getVersion()` – Tom Carmi May 08 '22 at 18:56
  • Also, I think the question was more about complex objects with nested objects, while you are talking more about the nullability of lists and strings – Tom Carmi May 08 '22 at 18:59
  • @TomCarmi You would typically do that example in 3 lines. Like: `SoundCard soundCard = computer == null ? null : computer.getSoundCard();` `USB usb = soundCard == null ? null : soundCard.getUSB();` `Version version = usb == null ? null : usb.getVersion();`. Each line resolves one step. But yes, I agree that it's too verbose. – bvdb Aug 01 '22 at 22:09
  • @TomCarmi in my interpretation the question was about "will there ever be an elvis operator in the future?". You may want to read the comments section underneath the very correct and brief answer of Brian Goetz. And you'll see that people usually don't take "No" for an answer. For that reason, I tried to explain the long and tiresome cultural evolution behind `null` in java. Even though I don't agree with the path it has chosen. – bvdb Aug 01 '22 at 22:23