【问题标题】:String vs StringBuilder - Number of objects [duplicate]String vs StringBuilder - 对象数[重复]
【发布时间】:2014-03-01 14:38:59
【问题描述】:

我遇到了两个代码 sn-ps,它们正在创建一个要进一步执行的查询:

StringBuilder stringBuilder = new StringBuilder(); 
stringBuilder.append("SELECT * FROM EMPLOYEE "); 
stringBuilder.append("WHERE SALARY > ? "); 
stringBuilder.append("GROUP BY DEPT");

String string = "SELECT * FROM EMPLOYEE " +
"WHERE SALARY > ? " +
"GROUP BY DEPT";

根据我的分析,sn-ps 都创建了 4 个对象。第一个 sn-p 创建一个 StringBuilder 对象和 3 个字符串对象,而第二个 sn-p 创建 4 个 String 对象。我的分析正确吗?

sn-p 1 比 sn-p 2 效率如何?

【问题讨论】:

标签: java string stringbuilder


【解决方案1】:

您的第一个分析是正确的,但第二个 sn-p 只创建 一个 字符串对象。因为,它是字符串字面量的编译时串联。

【讨论】:

  • 很明显,连接可以在编译时完成。但是,编译器有义务这样做吗?
  • 如今,当人们谈论没有 android 标签的“java”时,可以安全地假设它是热点编译器,然后是的,它将会发生。如果您构建自己的编译器,则没有义务进行编译时连接,因为保持原样在功能上仍然正确。
  • @NPE 根据JLS §15.18.1 我认为编译器没有义务这样做。
  • 感谢您的意见。
  • @DarshanMehta,不客气!
【解决方案2】:

不完全是……

第一个版本创建 1 个StringBuilderevery execution 和 3 个String 常量(创建/interned 每次 JVM 启动)。当您通过stringBuilder.toString() 使用该值时,它将在每次执行时创建另一个String 对象。

第二个创建 1 个String 常量(每次 JVM 启动创建/interned 一次),因为整个连接的值在编译时是已知的。效果等同于:

String string = "SELECT * FROM EMPLOYEE WHERE SALARY > ? GROUP BY DEPT";

【讨论】:

    【解决方案3】:

    字符串是不可变的,因此每次您执行连接(. 运算符)时,您都会在内存中创建一个新的字符串对象。使用 StringBuilder,您可以将文本添加到同一个对象,因此不需要创建新对象。

    【讨论】:

      【解决方案4】:

      StringBuilder 示例将创建 4 个对象。

      第二个示例将只创建一个字符串对象。即使您已经连接了 3 个 String 文字,模型 Java 编译器也足够聪明,可以检测到您已经连接了静态 String 文字,因此会将它们全部附加并创建一个 @987654324 @对象。

      因此,

      String string = "SELECT * FROM EMPLOYEE " +
      "WHERE SALARY > ? " +
      "GROUP BY DEPT";
      

      相同

      String string = "SELECT * FROM EMPLOYEE WHERE SALARY > ? GROUP BY DEPT";
      

      【讨论】:

        【解决方案5】:

        第一个 sn -p 创建 1 个对象。它在编译时连接。

        当您连接可变字符串时,StringBuilder 具有更好的性能。例如,用你的例子:

        StringBuilder stringBuilder = new StringBuilder(); 
        stringBuilder.append("SELECT * FROM EMPLOYEE "); 
        if(salary > 0) {
            stringBuilder.append("WHERE SALARY > ? "); 
        }
        if(group == true) {
            stringBuilder.append("GROUP BY DEPT");
        }
        
        String string = "SELECT * FROM EMPLOYEE ";
        if(salary > 0) {
            string = string + "WHERE SALARY > ? ";
        }
        if(group == true) {
            string = = string + "GROUP BY DEPT";
        }
        

        【讨论】:

          猜你喜欢
          • 2015-10-01
          • 1970-01-01
          • 2015-12-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多