是否有标准的Java NonNullable <t>泛型,如果没有,为什么不呢?</t>

时间:2011-06-21 15:03:18

标签: java generics null nullpointerexception non-nullable

@NotNull/@NonNull等注释的问题在于它们在运行时不会强制执行。我想做类似以下的事情:

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.
  }
  ...
}

某个地方是否存在标准NonNullable<T>通用,如果没有,是否有理由这是个坏主意?

4 个答案:

答案 0 :(得分:2)

我很确定它不存在。但是你可以建立自己的:

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;
    }

}

答案 1 :(得分:0)

没有必要为此使用特殊的包装类。如果您不想允许某些内容null,请确保在检查时给您的时间不是null。您可以使用标准Java执行此操作:

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

或者使用Guava,您可以使用Preconditions类将其简化为:

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

在Guava的r10中,在很长一段时间之前出现,你也可以使用Optional<T>(不可变)或Holder<T>(可变)。这些并不一定正是你所期待的,因为它们都被允许“缺席”(没有任何价值),但两者都不能包含nullHolder特别适用于您示例中的场景,因为您没有显示它是否使用任何值进行初始化(在创建时没有给出任何String,所以它必须最初缺席)。如果给出set,则NullPointerException方法会抛出null,就像您想要的那样。

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

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

使用HolderOptional时,通常应在调用isPresent()之前检查get(),因为如果不存在,则会IllegalStateException。或者,您可以使用or方法:

String definitelyNotNull = stringHolder.or("default");

答案 2 :(得分:0)

IntelliJ有@NotNull and @Nullable annotations。它使用IDE中的静态检查和字节码检测来在运行时执行检查。您也可以检测运行时检查。

答案 3 :(得分:-3)

怎么样:

NonNullable<?>