Возврат объекта Void

Каков правильный способ вернуть тип Void, если он не является примитивным? Например. В настоящее время я использую null, как показано ниже.

interface B<E>{ E method(); }

class A implements B<Void>{

    public Void method(){
        // do something
        return null;
    }
}

Ответ 1

Класс Void является неинтересным классом-заполнителем для ссылки на объект класса, представляющий ключевое слово void.

Таким образом, было бы достаточно любого из следующего:

  • с Object и возвратом new Object() или null
  • с Void и возвратом null
  • с NullObject вашего

Вы не можете сделать этот метод Void, а что-нибудь еще что-то возвращает. Поскольку это что-то игнорируется, вы можете вернуть что-либо.

Ответ 2

В Java 8 появился новый класс Optional<T>, который можно использовать в таких случаях. Чтобы использовать его, вы немного измените свой код следующим образом:

interface B<E>{ Optional<E> method(); }

class A implements B<Void>{

    public Optional<Void> method(){
        // do something
        return Optional.empty();
    }
}

Это позволяет вам гарантировать, что вы всегда получаете ненулевое возвращаемое значение из вашего метода, даже если нет возврата. Это особенно эффективно при использовании в сочетании с инструментами, которые обнаруживают, когда null может или не может быть возвращено, например. аннотации Eclipse @NonNull и @Nullable.

Ответ 3

Если вам просто не нужно что-то в качестве вашего типа, вы можете использовать void. Это можно использовать для реализации функций или действий. Затем вы можете сделать что-то вроде этого:

interface Action<T> {
    public T execute();
}

abstract class VoidAction implements Action<Void> {
    public Void execute() {
        executeInternal();
        return null;
    }

    abstract void executeInternal();
}

Или вы можете опустить абстрактный класс и выполнить возврат null в каждом действии, для которого не требуется возвращаемое значение.

Затем вы можете использовать следующие действия:

Для метода

private static <T> T executeAction(Action<T> action) {
    return action.execute();
}

вы можете называть его как

String result = executeAction(new Action<String>() {
    @Override
    public String execute() {
        //code here
        return "Return me!";
    }
});

или, для действия void (обратите внимание, что вы не присваиваете результат чему-либо)

executeAction(new VoidAction() {
    @Override
    public void executeInternal() {
        //code here
    }
});

Ответ 4

Нет универсального типа, который сообщает компилятору, что метод ничего не возвращает.

Я считаю, что соглашение заключается в использовании Object при наследовании в качестве параметра типа

ИЛИ

Разложите параметр типа вверх, а затем позвольте пользователям вашего класса создавать экземпляр с помощью Object и назначая объект переменной, введенной с помощью подстановочного символа ?:

interface B<E>{ E method(); }

class A<T> implements B<T>{

    public T method(){
        // do something
        return null;
    }
}

A<?> a = new A<Object>();