Необязательный Java 8 не может быть применен к интерфейсу - PullRequest
0 голосов
/ 17 января 2019

Используя Optional, я хочу вернуть определенную реализацию (First или Second) интерфейса в соответствии с результатом сопоставления. Это интерфейс, который First и Second реализовать:

public interface MyInterface {
    Number number();
}

Следующее Optional использование ошибочно:

final String string = ...                          // might be null
final Number number = Optional.ofNullable(string)
        .map(string -> new First())
        .orElse(new Second())                      // erroneous line
        .number();

orElse (com.mycompany.First) в опционально нельзя применить к (com.mycompany.Second)

Почему строка ошибочна, поскольку оба класса First и Second реализуют интерфейс MyInterface, а метод MyInterface::number возвращает Number? Как правильно это реализовать?

Ответы [ 4 ]

0 голосов
/ 17 января 2019

Так как объяснение верно и в других ответах, его тип выводится при использовании map, который выдает ошибку при использовании orElse, более чистым способом представления предложенного решения будет:

Optional.ofNullable(string)
        .map(s -> (MyInterface) new First()) // casting rather than binding here
        .orElse(new Second())
        .number();
0 голосов
/ 17 января 2019

Я бы написал это без явного приведения:

Optional.ofNullable(string)
        .map(s -> {
             MyInterface m = new First();
             return m;  
        })
        .orElse(new Second())
        .number();
0 голосов
/ 17 января 2019

Проблема в том, что Java выводит сопоставленный тип на First, а Second не является экземпляром First. Вам необходимо явно дать толчок Java, чтобы узнать правильный тип:

private static void main(String... args)
{
    final String string = "";
    final Number number = Optional.ofNullable(string)
        .<MyInterface>map(str -> new First())  // Explicit type specified 
        .orElse(new Second())
        .number();
}

Это общее ограничение вывода типа по цепочке методов. Это не ограничено Optional.

Было высказано предположение, что вывод по типу должен выполняться вдоль цепочек методов. Смотрите этот вопрос: Вывод общего типа не работает с цепочкой методов?

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

0 голосов
/ 17 января 2019

Я обнаружил, что метод Optional::map возвращает U, который не позволяет применить возвращенный First к другому типу, такому как Second. Явное приведение к его интерфейсу или требование его в методе map - вот путь:

final Number number = Optional.ofNullable("")
        .<MyInterface>map(string -> new First())
        .orElse(new Second())
        .number(); 

__

Редактировать : Я узнал об этом после публикации вопроса. Тем не менее, я сохраняю оба, так как я еще не нашел подобное решение где-либо еще.

...