【问题标题】:Guava ImmutableMap Builder syntaxGuava ImmutableMap Builder 语法
【发布时间】:2014-03-22 04:54:54
【问题描述】:

我已经使用 Guava 的 ImmutableMapBuilder 有一段时间了,而没有过多考虑它的工作原理/原因。我一直在按照Javadoc 描述的方式使用构建器:

ImmutableMap<String, Integer> WORD_TO_INT =
          new ImmutableMap.Builder<String, Integer>()
              .put("one", 1)
              .put("two", 2)
              .put("three", 3)
              .build();

我还看到了关于这种语法的示例 elsewhere

ImmutableMap<String,Integer> myMap = ImmutableMap.<String, Integer>builder()
    .put("one", 1) 
    .put("two", 2) 
    .put("three", 3) 
    .build();

两者似乎产生完全相同的结果。

快速浏览一下ImmutableMap source 表明第二个示例中的静态builder() 调用返回:new Builder&lt;K, V&gt;()

这两种方法之间似乎没有任何功能差异。

引擎盖下有什么区别吗?有任何理由偏爱其中一个吗?

编辑:添加字节码差异。

生成的字节码除了一行之外几乎相同:

方法一(Builder&lt;K,V&gt;):

static {};
     0  new com.google.common.collect.ImmutableMap$Builder [12]
     3  dup
     4  invokespecial com.google.common.collect.ImmutableMap$Builder() [14]
     7  ldc <String "key1"> [17]
     ........

方法二:(&lt;K,V&gt;builder())

static {};
     0  invokestatic com.google.common.collect.ImmutableMap.builder() : com.google.common.collect.ImmutableMap$Builder [12]
     3  ldc <String "key1"> [18]
     ........

之后它们几乎相同,考虑到来源差异,第一行不同是有道理的,但我不确定为什么第一行调用 dup 而第二行没有。

【问题讨论】:

    标签: java guava immutability


    【解决方案1】:

    不,它们是相同的。第一种语法的原因是它是一个很好的单行。

    第二种语法的原因是你可能有一个循环或其他流控制,你可能需要传递Builder

    例如:

    public static void main(final String[] args) throws Exception {
        final ImmutableList.Builder<Integer> lb = ImmutableList.builder();
        for (final String arg : args) {
            lb.add(Integer.parseInt(arg));
        }
    }
    

    在你说之前,是的,FluentIterable 在这种情况下可能会更好——但这只是一个例子。

    【讨论】:

    • 知道为什么dup 会出现在第一个字节码中吗?我对字节码知之甚少,不知道这是否是典型的。
    • @MagicMan 如果您查看源代码,您会发现方法不同 - 我对字节码不同并不感到惊讶。至于为什么它会重复这个值,我不确定。
    • 啊,只要没有大的区别我就放心。示例清楚地说明了我应该如何使用它,谢谢!
    • @MagicMan,您没有提供完整的字节码列表,但我相信在第一个示例中dup 之后会有类似invokespecial ...ImmutableMap$Builder.&lt;init&gt;() 的内容。这正是需要dup 的原因。在 Java 中构造是两个阶段的过程:首先,通过new 分配新内存,然后在该内存上调用构造方法(&lt;init&gt;)。所以duped 栈元素被构造函数消耗掉了。
    • @VladimirMatveev 啊,抱歉,刚刚编辑并添加了下一行。你是对的,确实是invokespecial....
    【解决方案2】:

    javadoc所述,生成的builder相当于ImmutableMap.Builder构造函数创建的builder。

    在应用 Builder 模式时编写这样的方法是一种很好的做法。这提供了一种流畅的使用方式,可以被视为“语法糖”。

    【讨论】:

      猜你喜欢
      • 2012-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-23
      • 2016-01-07
      • 2015-05-13
      • 1970-01-01
      • 2017-11-04
      相关资源
      最近更新 更多