@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>
通用,如果没有,是否有理由这是个坏主意?
答案 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>(可变)。这些并不一定正是你所期待的,因为它们都被允许“缺席”(没有任何价值),但两者都不能包含null
。 Holder
特别适用于您示例中的场景,因为您没有显示它是否使用任何值进行初始化(在创建时没有给出任何String
,所以它必须最初缺席)。如果给出set
,则NullPointerException
方法会抛出null
,就像您想要的那样。
final Holder<String> stringHolder = Holder.absent(); // nothing at first
public void mutate(String arg) {
stringHolder.set(arg);
}
使用Holder
或Optional
时,通常应在调用isPresent()
之前检查get()
,因为如果不存在,则会IllegalStateException
。或者,您可以使用or
方法:
String definitelyNotNull = stringHolder.or("default");
答案 2 :(得分:0)
IntelliJ有@NotNull and @Nullable annotations。它使用IDE中的静态检查和字节码检测来在运行时执行检查。您也可以检测运行时检查。
答案 3 :(得分:-3)
怎么样:
NonNullable<?>