21

One problem with using Guava's Optional type as arguments of methods is that you can't simply write

// method declaration
public void foo(Optional<String> arg);

// compiler error
foo(Optional.absent());

due to type inference failing but instead have to add the type explicitly:

// real method call
foo(Optional.<String> absent());

How can I avoid it?

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • 6
    There's not really a better way, but FYI, `Optional` tends to be more commonly used as a return value than as a method argument type. (It's much easier to forget that a return value from a method might be null than an argument to the method you're writing.) – Louis Wasserman Aug 01 '12 at 12:31
  • With a complicated expression, I use a local variable of a proper type (on the RHS of the assignment no type variable is needed) in order to get something more readable. But here nothing can be done until resolution comes (probably JDK8). – maaartinus Aug 01 '12 at 15:28
  • 3
    @LouisWasserman There are still benefits to using `Optional` as argument: 1) making it clear to users of API that an argument can be absent; 2) making it easy to pass return value of another method to yours. – Alexey Romanov Aug 01 '12 at 21:03
  • I use the Optional in combination with the Jersey framework. E.g. a @QueryParameter might be not given when the method is called. When I write a unit test however, i need to call using a typed absent Optional – Raffael Aug 23 '12 at 13:57

3 Answers3

8

If you are dealing with a small set of Optional<> types (e.g., mostly strings or a handful of other types), just create some helper methods that bind the type argument for you:

public final class AbsentValues {
    public static Optional<String> absentString() {
        return Optional.<String>absent();
    }
}

You can even import these statically to result in cleaner code:

import static AbsentValues.*;

...

foo(absentString());

For less common Optional<> types, just specify the type argument explicitly. It may not be pretty, but it's correct.

Mike Strobel
  • 25,075
  • 57
  • 69
-1

So, this is the right way to do this. If not for anything else, let me at least show it here for my own future reference, for everyone who doesn't read questions, like myself :) Thanks to ColinD (and Alexey).

foo(Optional.<String>absent())
Sander Verhagen
  • 8,540
  • 4
  • 41
  • 63
-4

Just when writing the question, I thought of having

public class GuavaConstants {
    @SuppressWarnings( { "raw" })
    public static final Optional ABSENT = Optional.absent();

    // similar for empty ImmutableList, etc.
}

and then the call can look like

@SuppressWarnings( { "unchecked" })
foo(GuavaConstants.ABSENT);

Is there a better approach?

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • 16
    Yes, `foo(Optional.absent())` is better. This doesn't strike me as something you should be doing at all. – ColinD Aug 01 '12 at 22:30
  • 3
    @ColinD, please post this as an answer, I for one will upvote it right away. The accepted (and only) answer is quite nasty. – Zoltán Jul 17 '13 at 15:58