5 ms·
The process control changes might not seem so exciting but they fix some serious pain points, I'm very excited to integrate these into my code. Optional is ano
by ZoFreX 12y ago
The process control changes might not seem so exciting but they fix some serious pain points, I'm very excited to integrate these into my code.
Optional is another nice addition, I've been creating one myself in all Java projects I've created since I first encountered it in Rust.
- maaaats 12y agoAnd now frameworks can finally supply Optionals, since it before only lead to multiple competing implementations.
- mike_hearn 12y agoBut is it really better than @Nullable?
- jburwell 12y agoCompletely different concepts. @Nullable expresses an precondition indicating whether or not something can be null. One example of its use is by static analyzers such as Findbugs to find misuse to APIs. In contrast, Optional encapsulates the behavior when something is not present (or null) -- very similar to the Null Object pattern [1]. Used together, you can build an API that permits encapsulates the present/not present behavior and ensure that it is not passed a null reference to the Optional instance. [1]: http://en.wikipedia.org/wiki/Null_Object_pattern http://en.wikipedia.org/wiki/Null_Object_pattern
- vog 12y agoIt is a pity that Qt is not mentioned in that article. AFAIK, It is the only widely-used C++ library that implements null objects consequently. Ever wondered why the Qt framework doesn't use any exceptions or C-style error codes? It is solely because of proper use of Null objects.
- DCKing 12y agoOf course it's better than @Nullable. @Nullable-annotated code still compiles your NullPointerException-throwing code, using Optional won't.
- mike_hearn 12y agoAssuming that nobody screws up and assigns null to an Optional return result/variable instead of Optional.empty(), or calls Optional.get() without remembering to check ... in other words, it's very much like @Nullable when using a compiler that understands it, except it causes problems with overloading and reflection as noted above due to generics type erasure. If you want code that won't compile due to @Nullable violations I think the Checker framework can give you that, or you can use an IDE that flags violations like IntelliJ and just treat any static analysis warning in that category like a compile failure for your own purposes. The nice think about nullity annotations is that the newest JVM languages like Ceylon and Kotlin are building nullity into their type systems, so if you annotate an API in this way, code written in these new languages will know automatically that the reference can be null and the compiler won't let you access it at all until you tested or asserted away the nullness. The upgrade path for Kotlin especially is looking like it could be quite strong, so I think I'll be sticking with @Nullable for now in the hope that later on we get "real" type system integration via newer languages.
- matwood 12y agoI don't think @NotNull/@Nullable go away completely, but the use of optional makes dealing with nullables much easier. I think this is a much cleaner ways to deal with possible nulls: public ImmutableMap<String, Long> getSessionTime(HttpServletRequest request) { return Optional.ofNullable(request.getSession(false)) .map(s -> ImmutableMap.of("lastAccessedTime", s.getLastAccessedTime())) .orElseThrow(IllegalStateException::new); } If/When HttpServletRequest is updated to support Optional it can return it directly instead of the caller having to do it, and that is when Java will really see the upside.
- mike_hearn 12y ago
- lmm 12y agoGiven how few tools understand @PolyNull, yes. Better to have one type system rather than two.
- deleted 12y ago[deleted]
- hutteman 12y agoI would say in most cases: no. Due to backwards compatibility concerns, no existing Java APIs that may currently return null can ever be changed to return Optionals instead, so nulls need to be dealt with regardless. Also, there's technically nothing stopping an Optional value from actually being null itself, or from developers calling Optional.get() without checking isPresent(), just like they might currently use a reference without checking for null. I personally really wish jsr305 had been adopted in Java8, and their existing APIs retrofitted with these annotations. http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html http://www.oracle.com/technetwork/articles/java/java8-option... describes Optional, and compares it to how in Groovy, the safe navigation and elvis operators allow you to write code like this: String version = computer?.getSoundcard()?.getUSB()?.getVersion() ?: "UNKNOWN"; With Java 8 Optionals, this instead becomes: String version = computer.flatMap(Computer::getSoundcard) .flatMap(Soundcard::getUSB) .map(USB::getVersion) .orElse("UNKNOWN"); which is not only much longer and arguably uglier, but also forces developers to suddenly have to worry about applying lambdas using flatmap vs map, where conceptually you're really just dealing with method calls. New languages like Kotlin solve this much better in my opinion by introducing nullable vs nonnullable types. While Java can unfortunately never adopt this due to backwards compatibility issues, @Nullable and @Nonnull will do most of the time, and hopefully we'll see operators like ?. and ?: in future versions of Java.
- hibikir 12y agoWhile I've enjoyed the Elvis operator in Groovy, the point of optional is to make null go away altogether. In Groovy, you are never guaranteed anything isn't null, so the end result is that you will Elvis everything. While this is easier than the good old if statements, you are still paying for the penalty of a billion ifs in bytecode. With option, you clearly declare what is safe, and what isn't, and the compiler won't let you screw up. You can decide which layer of your code handles the empty case, and lots of unnecessary ifs go away from the bytecode itself, so the app will run faster, and you know when you have to even consider the null case. Now, doing that in Groovy is rather silly, because your language is dynamic and your types are optional, so all of this compile time safety would not provide any value anyway. Option is just the way you'd solve the problem in the strongly typed way. It's how you handle it in Scala, for instance, and how Haskell would deal with it. As far as using flatmaps and maps to work with optionals, yes, it's a chore. I'd argue it's borderline abuse of the stream operators, as treating Option as a collection is ugly. That said, putting yourself in a situation where you chain 3 optional getters is also object design from hell, so one should avoid putting themselves in that position altogether. In Scala, instead of flatmapping single optionals, we often getOrElse(), or use pattern matching as an extractor. Now that's a feature I would like to see Java 'steal' from the Scalas and Erlangs of the world, but I do not see that happening.
- matwood 12y agoFor those still on pre Java 8, Google's Guava also adds Optional and other useful things like immutable collections.
- meddlepal 12y agoMy problem with Optional<T> is that it basically makes overloaded Java methods impossible because of erasure. I'm worried that it is going to start getting overused; the JDK developers really only intended for its use in the Streams API.
- tel 12y agoCould you explain that a little bit more? I'm using to Maybe from Haskell and am curious what might be missing from Java's Optional.
- deleted 12y ago[deleted]
- matwood 12y agoBasically, because of type erasure you cannot have overloaded methods using different Optional types. So test(Optional<A> a); is the same method as test(Optional<B> b); I think you can define the types to get around it, but that is messy and a PITA. For example, class OptionalA extends Optional<A>.
- dignati 12y agoWow that's a real pain point. Why would they even do that, is there a use case?
- ZoFreX 12y agoBackward compatibility - you could run an application that uses generics, introduced in Java 1.5, on a Java 1.4 VM. At the time that was pretty amazing. These days, with so many backward compatibility-breaking changes being introduced, it doesn't feel so great.
- deleted 12y ago[deleted]
- 12y ago
- smoyer 12y agoI still prefer using JSR-305 annotations/tools (like Findbugs) to do static analysis. Reification should help Optional<?> become more useful, but why would you ask for run-time checking when in most cases compile-time checking identifies the problems?
- mumrah 12y agoGuava has a nice explanation: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained https://code.google.com/p/guava-libraries/wiki/UsingAndAvoid.... Essentially, it forces you to actively think about the "absent" case when programming.