代码之家  ›  专栏  ›  技术社区  ›  HenryNguyen

Java8通用拼图

  •  7
  • HenryNguyen  · 技术社区  · 7 年前

    我使用的是Java 1.8.0_151,有些代码无法编译,我不理解:

    Optional optional = Optional.of("dummy"); 
    Optional<Boolean> result1 = optional.map(obj -> true);     // works fine
    boolean result2 = result1.orElse(false);                   // works fine
    boolean result3 = optional.map(obj -> true).orElse(false); // compilation error: Incompatible types: required boolean, found object
    Object result4 = optional.map(obj -> true).orElse(false); // works fine
    

    为什么它在上运行良好 result1 但在上出现编译错误 result3 ?
    其他信息:

    • 在第一行,当我改变 Optional Optional<String> ,result3也能够编译
    • 当我休息的时候 结果3 分成两行:like 结果1 result2 , 结果3 能够编译
    3 回复  |  直到 7 年前
        1
  •  9
  •   Eugene    7 年前

    一旦你失去了类型安全性,链式调用也会失去它。那就是 Optional<Object> != Optional . 所以当你这么做的时候

     Optional optional = Optional.of("dummy");
     optional.map()
    

    这个 map 只能接受原始 Function 除此之外,不会返回 Object 明显地

    正确的方法是添加类型信息:

    Optional<String> optional = Optional.of("dummy");
    

    或者你可以不安全地施放:

    boolean result3 = (boolean) optional.map(obj -> true).orElse(false)
    
        2
  •  4
  •   Eran    7 年前

    optional 是生的 Optional 所以 optional.map(obj -> true) 返回原始 可选择的 orElse(false) 返回一个 Object ,不是 Boolean . 编译器不知道如何取消装箱 对象 boolean .

    通过改变

    Optional optional = Optional.of("dummy"); 
    

    Optional<Object> optional = Optional.of("dummy"); 
    

    Optional<String> optional = Optional.of("dummy"); 
    

    从现在起,您将克服这个错误 可选择的地图(obj->true) 将返回 Optional<Boolean> orElse(假) 将返回一个 布尔型 .

        3
  •  0
  •   HenryNguyen    7 年前

    谢谢你的回答。我只是想详细说明一下为什么它会起作用 resutl1 但不是 result3 日期:

    Optional<Boolean> result1 = optional.map(obj -> true);     // works fine
    boolean result2 = result1.orElse(false);                   // works fine
    boolean result3 = optional.map(obj -> true).orElse(false); // compilation error: Incompatible types: required boolean, found object
    

    在…上 result1 这个 optional 变量是原始类型,所以 optional.map(obj -> true) 返回了一个 Optional 原始类型。

    当我宣布 Optional<Boolean> result1 , 可选择的 原始类型为 自动浇铸 Optional<Boolean>
    另一方面 optional.map(obj -> true).orElse(false); 失败,因为原始类型 可选择的 对象无法调用 .orElse(false)

    原始类型的这种行为的另一个例子是:

    List li = new ArrayList<String>();
    List<String> li1 = li;
    List<Integer> li2 = li;
    List<Map> li3 = li;
    
    li1.add("WWW");
    li2.add(444);
    li3.add(new HashMap());
    

    适用于所有场景 li 对象将包含字符串、整数和HashMap()。这个 li1, li2, li3 自动转换为非原始类型。