代码之家  ›  专栏  ›  技术社区  ›  Nikolas Charalambidis

Java 8 Optional无法应用于接口

  •  12
  • Nikolas Charalambidis  · 技术社区  · 7 年前

    使用 Optional ,我想返回某个实现( First Second) 根据映射结果创建一个接口。这就是 第一 Second 实施:

    public interface MyInterface {
        Number number();
    }
    

    以下 用法错误:

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

    奥莱尔斯 (com.mycompany.First) 在可选项中,不能应用于 (com.mycompany.Second)

    既然这两个类都有,为什么这一行是错误的 第一 第二 实现接口 MyInterface MyInterface::number 返回 Number ? 如何正确实施这一点?

    4 回复  |  直到 7 年前
        1
  •  12
  •   Naman    7 年前

    我发现这个方法 Optional::map U 这不允许应用程序返回 First 到另一种类型,例如 Second map

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

    __

    当前位置我在发布问题后发现了这一点。然而,我保留了这两个,因为我还没有在其他地方找到类似的解决方案。

        2
  •  6
  •   Michael    7 年前

    推断 First Second 不是一个例子 第一 . 您需要显式地给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 .

    有人建议沿着方法链进行类型推断。见这个问题: Generic type inference not working with method chaining?

    也许在未来的Java版本中,编译器会足够聪明地解决这个问题。谁知道呢。

        3
  •  3
  •   Eugene    7 年前

    我会在没有明确演员阵容的情况下写道:

    Optional.ofNullable(string)
            .map(s -> {
                 MyInterface m = new First();
                 return m;  
            })
            .orElse(new Second())
            .number();
    
        4
  •  1
  •   Felix    6 年前

    你也可以写:

    Optional.ofNullable(string)
        .map(s -> new First())
        .filter(MyInterface.class::isInstance)
        .map(MyInterface.class::map)
        .orElse(new Second())
        .number()
    

    或者,在代码库中添加一个实用函数:

    // the Class Object is unused and only present so the Compiler knows which Type you actually want
    public static <T, R> Function<? super T, R> mapAs(Function<? super T, ? extends R> mappingFunction, Class<R> clazz) {
        return mappingFunction::apply;
    }
    
    Optional.ofNullable(string)
        .map(mapAs(s -> new First(), MyInterface.class))
        .orElse(new Second())
        .number()
    
        5
  •  0
  •   Naman    7 年前

    这个解释在其他答案中也是正确的,它是在使用 map 那就错了 orElse

    Optional.ofNullable(string)
            .map(s -> (MyInterface) new First()) // casting rather than binding here
            .orElse(new Second())
            .number();
    
    推荐文章