Существует ли стандартная Java NonNullable <T>generic, и если нет, то почему? - PullRequest
4 голосов
/ 21 июня 2011

Проблема с аннотациями, такими как @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 ]

2 голосов
/ 21 июня 2011

Я почти уверен, что его не существует.Однако вы можете создать свой собственный:

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

}
0 голосов
/ 21 июня 2011

IntelliJ имеет @ NotNull и @Nullable аннотации .Он использует статические проверки в IDE и инструментарий байт-кода для выполнения проверок во время выполнения.Вы также можете проверять время выполнения.

0 голосов
/ 21 июня 2011

А как же:

NonNullable<?>

0 голосов
/ 21 июня 2011

Для этого не нужно использовать специальный класс-обертку.Если вы не хотите, чтобы что-то было null, убедитесь, что оно не null в тот момент, когда вам дадут чек.Вы можете сделать это со стандартным Java:

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

или с Guava , вы можете использовать класс Предварительные условия , чтобы упростить его до:

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

В r10 из Гуавы, появившегося некоторое время назад, вы также можете использовать Необязательный (неизменяемый) или Держатель (изменяемый).Это не обязательно то, что вы ищете, поскольку им обоим разрешено быть «отсутствующими» (не имеющими значения), но ни один из них не может содержать 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");
...