возврат пустого объекта


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

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

class A implements B<Void>{

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

4 ответа:

Void класс является uninstantiable класс заполнитель для хранения ссылки на объект класса, представляющего в Java ключевое слово Void.

поэтому достаточно любого из следующих:

  • параметризация с Object и возврат new Object() или null
  • параметризация с Void и возврат null
  • параметризация с NullObject твой

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

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 может или не может быть возвращен, например, затмение @NonNull и @Nullable Примечание.

Если вам просто ничего не нужно, как ваш тип, вы можете использовать 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
    }
});

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

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

или

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

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

class A<T> implements B<T>{

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

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