当Optional <Object>被期望作为参数时,编译器是否解析了空值,这是一个好主意吗?

Whi*_*cal 6 java nullable java-8

这显然是非常有用的,我开始认为我错过了避免它的理由,因为我确信甲骨文会这样做.对我来说,这将是Optional上最有价值的功能.

public class TestOptionals{
    public static void main(String[] args) {
        test(null);
    }

    public static void test(Optional<Object> optional){
        System.out.println(optional.orElse(new DefaultObject()));
    }
}
Run Code Online (Sandbox Code Playgroud)

(这会抛出NullPointerException)

如果没有该功能,我会在参数中使用Optional看起来过于冗长.我更喜欢一个简单的Object optional签名,并通过if (null = optional)创建对象进行检查,以便稍后进行比较.如果这不能帮助您检查null,则没有价值

Stu*_*rks 16

有一个巨大的讨论,Optional对所有各种Java邮件列表,包括数百封邮件.进行网络搜索

site:mail.openjdk.java.net optional
Run Code Online (Sandbox Code Playgroud)

你会得到许多链接.当然,我甚至无法总结所提出的所有问题.存在很多争议,并且对于应该在平台上添加多少 "可选性" 存在相当广泛的意见.有些人认为不应该添加图书馆解决方案; 有些人认为没有语言支持,图书馆解决方案就没用了; 有些人认为图书馆解决方案没问题,但是对于它应该包含的内容存在大量的争论; 等等.有关一些观点,请参阅Brian Goetz在lambda-dev邮件列表上的此消息.

lambda团队做出的一个务实的决定是任何类似可选的功能都不会涉及任何语言变化.语言和编译器团队已经掌握了lambda和default方法.这些当然是主要的优先事项.实际上,选择要么添加Optional为库类,要么根本不添加.

当然人们都知道支持选项类型的其他语言的类型系统.这将是Java类型系统的一个重大变化.事实是,在过去20年的大部分时间里,引用类型已经可以为空,并且有一个单一的无类型null值.改变这是一项艰巨的任务.甚至可能无法以兼容的方式执行此操作.我不是这方面的专家,但大多数这样的讨论都很快就会进入杂草.

可能更容易处理的较小变化(Marko Topolnik也提到)是考虑引用类型之间的关系和Optional拳击之间的关系,然后引入已经在语言中的自动装箱/自动装箱的支持.

这有点问题.当在Java 5中添加自动(联合)装箱时,它使大量案例更好,但它为语言添加了许多粗糙的边缘.例如,通过自动拆箱,现在可以使用<>比较盒装Integer对象的值.不幸的是,使用==仍然比较引用而不是值!拳击也使重载决议更加复杂; 它是当今语言中最复杂的领域之一.

现在让我们考虑引用类型和Optional类型之间的自动(联合)装箱.这可以让你做到:

Optional<String> os1 = "foo";
Optional<String> os2 = null;
Run Code Online (Sandbox Code Playgroud)

在此代码中,os1最终将作为一个盒装字符串值,os2最终将作为一个空的Optional.到现在为止还挺好.现在相反:

String s1 = os1;
String s2 = os2;
Run Code Online (Sandbox Code Playgroud)

现在我s1会得到未装箱的字符串"foo",并且我会猜到s2它将被取消装箱null.但重点Optional是要使这种拆箱明确,这样程序员就会面临一个关于如何做空Optional而不是让它变成空洞的决定null.

嗯,所以也许让我们只做自动装箱Optional而不是自动装箱.让我们回到OP的用例:

public static void main(String[] args) {
    test(null);
}

public static void test(Optional<Object> optional) {
    System.out.println(optional.orElse(new DefaultObject()));
}
Run Code Online (Sandbox Code Playgroud)

如果你真的想使用Optional,你可以手动将它包装成一行:

public static void test(Object arg) {
    Optional<Object> optional = Optional.ofNullable(arg);
    System.out.println(optional.orElse(new DefaultObject()));
}
Run Code Online (Sandbox Code Playgroud)

显然,如果您不必编写此文件可能会更好,但是需要大量的语言/编译器工作以及兼容性风险来保存这行代码.是不是真的值得吗?

似乎正在进行的是,这将允许调用者传递null,以便对被调用者具有某些特定含义,例如"使用默认对象".在小例子中,这似乎很好,但总的来说,加载语义null越来越似乎是一个坏主意.所以这是不为拳击添加特定语言支持的另一个原因null.该Optional.ofNullable()方法主要是为了弥合使用的null代码和使用的代码之间的差距Optional.