草庐IT

java - 如果在将Optional <Object>作为参数时,编译器将解析为null,那是一个好主意吗?

coder 2024-03-23 原文

这显然非常有用,以至于我开始认为我缺少避免这种情况的理由,因为我确信Oracle会做到这一点。对我来说,这将是Optional上最有值(value)的功能。

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()));
    }
}

(这将引发NullPointerException)

如果没有该功能,则使用Optional作为参数会显得太冗长。
我更喜欢简单的Object optional签名,
通过if (null = optional)检查它是否创建了对象,这是可选的,以便以后进行比较。如果这不能帮助您检查null则没有任何值(value)

最佳答案

在所有各种Java邮件列表中,对Optional进行了 HUGE 讨论,其中包括数百条消息。进行网络搜索

site:mail.openjdk.java.net optional

您将获得许多链接。当然,我什至不希望总结所提出的所有问题。有很多争议,关于应该向平台添加多少“可选性”的意见也很广泛。有些人认为根本不应该添加图书馆解决方案。有些人认为没有语言支持的图书馆解决方案是无用的;有些人认为图书馆解决方案可以,但是对于其中应该包含的内容有很多疑问。等等。请参阅lambda-dev邮件列表上的message from Brian Goetz,以了解更多信息。

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

当然,人们知道支持选项类型的其他语言的类型系统。这对Java的类型系统将是一个巨大的改变。事实是,在过去的20年中的大多数时间里,引用类型都是可为空的,并且只有一个未键入的null值。改变这一点是一项艰巨的任务。甚至不可能以兼容的方式执行此操作。我不是该领域的专家,但是大多数此类讨论往往很快就进入了野草。

可能更易于处理的一个较小更改(也由Marko Topolnik提及)是将引用类型和Optional之间的关系视为一种装箱,然后引入该语言中已经存在的对自动装箱/自动拆箱的支持。

这已经有些问题了。在Java 5中添加了自动装箱后,它使许多情况变得更好了,但给该语言增加了很多粗糙的地方。例如,通过自动拆箱,现在可以使用<>比较装箱后的Integer对象的值。不幸的是,使用==仍然会比较引用而不是值!装箱也使重载解析变得更加复杂。这是当今语言中最复杂的领域之一。

现在,让我们考虑一下引用类型和Optional类型之间的自动装箱。这可以让您执行以下操作:
Optional<String> os1 = "foo";
Optional<String> os2 = null;

在此代码中,os1最终将作为一个装箱的字符串值,而os2最终将作为一个空的Optional。到目前为止,一切都很好。现在相反:
String s1 = os1;
String s2 = os2;

现在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()));
}

如果您确实想使用Optional,可以手动将其装箱成一行:
public static void test(Object arg) {
    Optional<Object> optional = Optional.ofNullable(arg);
    System.out.println(optional.orElse(new DefaultObject()));
}

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

似乎正在发生的事情是,这将允许调用者传递null以便对被调用者具有某些特定含义,例如“使用默认对象”。在较小的示例中,这似乎很好,但总的来说,将语义加载到null上似乎越来越不是一个好主意。因此,这是不为null装箱添加特定语言支持的另一个原因。 Optional.ofNullable()方法主要用于弥合使用null的代码和使用Optional的代码之间的鸿沟。

关于java - 如果在将Optional <Object>作为参数时,编译器将解析为null,那是一个好主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28663040/

有关java - 如果在将Optional <Object>作为参数时,编译器将解析为null,那是一个好主意吗?的更多相关文章

  1. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  2. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

  5. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  6. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  7. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  8. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  9. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  10. ruby-on-rails - Nokogiri:使用 XPath 搜索 <div> - 2

    我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll

随机推荐