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

添加一个空字符串vs toString-为什么不好?

  •  7
  • corgrath  · 技术社区  · 15 年前

    根据PMD工具,以下是一种不好的做法:

    String s = "" + 123; // bad 
    String t = Integer.toString(456); // ok 
    
    
    This is an inefficient way to convert any type to a `String`.
    

    为什么这是一件坏事?

    4 回复  |  直到 15 年前
        1
  •  14
  •   stacker    15 年前
    String s = "" + 123; // bad     
    String t = Integer.toString(456);
    

    将编译为:

    String s = "123";
    String t = Integer.toString(456);
    

    核对 JAD

    public static void main(String args[])
    {
    //    0    0:ldc1            #16  <String "123">
    //    1    2:astore_1
    //    2    3:sipush          456
    //    3    6:invokestatic    #18  <Method String Integer.toString(int)>
    //    4    9:astore_2
    //    5   10:getstatic       #24  <Field PrintStream System.out>
    //    6   13:new             #30  <Class StringBuilder>
    //    7   16:dup
    //    8   17:aload_1
    //    9   18:invokestatic    #32  <Method String String.valueOf(Object)>
    //   10   21:invokespecial   #38  <Method void StringBuilder(String)>
    //   11   24:aload_2
    //   12   25:invokevirtual   #41  <Method StringBuilder StringBuilder.append(String)>
    //   13   28:invokevirtual   #45  <Method String StringBuilder.toString()>
    //   14   31:invokevirtual   #48  <Method void PrintStream.println(String)>
    //   15   34:return
    }
    

    编辑:

    对于非常量值:

    int i = 123;
    String s = (new StringBuilder()).append(i).toString();
    String t = Integer.toString(i);
    System.out.println((new StringBuilder(String.valueOf(s))).append(t).toString());
    
        public static void main(String args[])
        {
        //    0    0:bipush          123
        //    1    2:istore_1
        //    2    3:new             #16  <Class StringBuilder>
        //    3    6:dup
        //    4    7:invokespecial   #18  <Method void StringBuilder()>
        //    5   10:iload_1
        //    6   11:invokevirtual   #19  <Method StringBuilder StringBuilder.append(int)>
        //    7   14:invokevirtual   #23  <Method String StringBuilder.toString()>
        //    8   17:astore_2
        //    9   18:iload_1
        //   10   19:invokestatic    #27  <Method String Integer.toString(int)>
        //   11   22:astore_3
        //   12   23:getstatic       #32  <Field PrintStream System.out>
        //   13   26:new             #16  <Class StringBuilder>
        //   14   29:dup
        //   15   30:aload_2
        //   16   31:invokestatic    #38  <Method String String.valueOf(Object)>
        //   17   34:invokespecial   #44  <Method void StringBuilder(String)>
        //   18   37:aload_3
        //   19   38:invokevirtual   #47  <Method StringBuilder StringBuilder.append(String)>
        //   20   41:invokevirtual   #23  <Method String StringBuilder.toString()>
        //   21   44:invokevirtual   #50  <Method void PrintStream.println(String)>
        //   22   47:return
        }
    
        2
  •  22
  •   Péter Török    15 年前

    它效率很低,因为它涉及到不需要的字符串串联,因此需要创建一个或两个额外的字符串 String 对象-尽管我相信JIT可以优化它。

    对我来说,更大的问题是代码不够清晰。打电话 toString 是一个标准的习惯用法,每个Java开发人员都能理解(希望:-),所以您应该更喜欢这样。

        3
  •  6
  •   jkff    15 年前

    扩展到“+String.valueOf值(yourObject)并因此执行不需要的连接。连接包括分配一个额外的字符串,并对字符串的值进行额外的复制。

        4
  •  0
  •   Dead Programmer    15 年前
    String s = "" + 123; // bad
    

    上面的代码创建一个临时字符串,将“”和123组合起来