4

The problem with annotations such as @NotNull/@NonNull is that they aren't enforced at runtime. I want to do something like the following:

class Foo {
  String nullable_string;
  final NonNullable<String> nn_string = new NonNullable<String>();
  ...
  public void mutate(String arg) {
    mutable_string = arg;  // arg could be null
    nn_string.set(arg);    // throws NullPointerException for me if arg is null.
  }
  ...
}

Does a standard NonNullable<T> generic exist somewhere, and if not, is there a reason it's a bad idea?

Jeremy
  • 41
  • 2
  • 2
    What would you expect from a NonNullable generic like that. It still extends Object in it's core; and every Object can reference null. No matter how NonNullable is build; I can still do `NonNullable nn = null;` – Yhn Jun 21 '11 at 15:06
  • @Yhn: The point of such a class wouldn't be to ensure that a reference of type `NonNullable` could never be `null` but to ensure that it doesn't _contain_ `null`. That said, a `NonNullable` reference shouldn't ever be `null`, and that can be ensured by things like assigning an instance to a `final` field like in the example. – ColinD Jun 21 '11 at 16:00
  • See JSR 305 status: http://stackoverflow.com/questions/2289694/what-is-the-status-of-jsr-305 – Christophe Roussy Jul 25 '16 at 12:16
  • I mostly use `import javax.annotation.xxx` – Christophe Roussy Jul 25 '16 at 12:42

4 Answers4

2

I'm pretty sure that it does not exist. However you can built your own:

public class NonNullable<T> {

    private T element;

    public void set(T element) {
        if (element == null)
            throw new NullPointerException("Parameter was null!");
        else
            this.element = element;
    }

}
Thomas Jungblut
  • 20,854
  • 6
  • 68
  • 91
0

There's no need to use a special wrapper class for that. If you don't want to allow something to be null, ensure it isn't null the moment it's given to you with a check. You can do this with standard Java:

if (arg == null)
  throw new NullPointerException();
this.string = arg;

Or with Guava, you can use the Preconditions class to simplify it to:

this.string = checkNotNull(arg); // using static import

In r10 of Guava, coming sometime before too long, you could also use an Optional<T> (immutable) or a Holder<T> (mutable). These aren't necessarily exactly what you're looking for since they are both allowed to be "absent" (holding no value), but neither may ever contain null. Holder in particular seems like it could work for the scenario in your example, since you don't show it being initialized with any value (it isn't given any String when it's created, so it must initially be absent). Its set method throws NullPointerException if given null, just like you want.

final Holder<String> stringHolder = Holder.absent(); // nothing at first

public void mutate(String arg) {
  stringHolder.set(arg);
}

When using a Holder or Optional, you should generally check that it isPresent() before calling get() since it'll throw IllegalStateException if absent. Alternatively you can use the or method:

String definitelyNotNull = stringHolder.or("default");
ColinD
  • 108,630
  • 30
  • 201
  • 202
  • You should throw `IllegalArgumentException` instead of `NullPointerException` if null is not allowed. Since it's an illegal argument, `IllegalArgumentException` is the appropriate exception. – Steve Kuo Jun 21 '11 at 15:34
  • @Steve: There are two camps on that, but the general consensus among Java programmers I know of is that `NullPointerException` is what should be thrown when an argument is `null` because it is the more specific exception in that case. – ColinD Jun 21 '11 at 15:36
  • Yup, looks like `IllegalArgumentException` vs `NullPointerException` is is heavily debated http://stackoverflow.com/questions/3881/illegalargumentexception-or-nullpointerexception-for-a-null-parameter – Steve Kuo Jun 21 '11 at 16:28
  • 1
    The wrapper class prevents the code duplication implicit in that arg check you wrote out, and ensures that if the value is set in multiple places in the class implementation, any null is caught. Holder looks like about the right concept, but we're not using Guava. And you're right, "absent" is clearly a concept that NonNullable has to have to work if it can be created without an argument. – Jeremy Jun 21 '11 at 20:16
  • @ColinD, are you serious? It would be beneficial to specify non-nullity in the interface - therefore, prior to calling the function, at parameter creation the check is already enforced. Fail early? Annotiations are not enforced (nullability difficult to determine at compile time), and we don't want to duplicate code in the function bodies. The need seems **very** obvious to me. I'm surprised that java does not have such a type. – Werner Erasmus Nov 04 '16 at 09:34
0

IntelliJ has @NotNull and @Nullable annotations. It uses static checks in the IDE and byte-code instrumentation to perform the checks at runtime. You could also instrument runtime checks as well.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
-4

What about:

NonNullable<?>

Snicolas
  • 37,840
  • 15
  • 114
  • 173