繁体   English   中英

字符串连接成StringBuilder java

[英]String concatenation into StringBuilder java

我有一个遗留Java文件,它使用字符串连接来构建巨大的String对象。这是一个严重的性能问题。是否存在这样的方法,它执行以下操作

String test="I am a very bad programmer"
+"to use concatenation"
+"Instead of StringBuilder"
+" or StringBuffer";

StringBuilder strBuilder= new StringBuilder();
strBuilder.append("I am a bad programmer");
strBuilder.append("to use concatenation");
strBuilder.append("Instead of StringBuilder");
strBuilder.append(" or StringBuffer");
String str= strBuilder.toString();

基本上我需要一个java中的存根只是为了给一个String实例化作为输入并转换成StringBuilder.Anybody过去试过这个?

不,这不是性能问题。 如果你串联内联字符串(就像你展示的那样)而不是使用循环,那么编译器会自动将+转换为使用StringBuilder 查看java.lang.String的文档

Java语言为字符串连接运算符(+)提供特殊支持,并为其他对象转换为字符串。 字符串连接是通过StringBuilder(或StringBuffer)类及其append方法实现的。 字符串转换是通过方法toString实现的,由Object定义并由Java中的所有类继承。 有关字符串连接和转换的其他信息,请参阅Gosling,Joy和Steele,Java语言规范。

更进一步 - 编译器可能会使用这些都是字符串常量并在运行时( JLS 引用 )之前连接它们的事实

像示例中的固定文字比使用StringBuilder更有效。

固定文字将由编译器检测,并将内联为单个值,因此两行

String s = "one" + "two" + "three";

String s = "onetwothree";

将生成完全相同的字节码。

如果连接不是使用文字而是使用函数调用,则图片是不同的。

当你需要动态追加字符串时,首选StringBuilder而不是StringBuffer,因为它不会同步,因为它稍快一些。

这是示例字节码:

public class Test
{
   private String s = "one" + "two" + "three";
}

public class Test2
{
   private String s2 = "onetwothree";
}

这些类的生成字节码是:

c:\Temp>javap -c Test
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   aload_0
   5:   ldc     #2; //String onetwothree
   7:   putfield        #3; //Field s:Ljava/lang/String;
   10:  return
}
c:\Temp>javap -c Test2
Compiled from "Test2.java"
public class Test2 extends java.lang.Object{
public Test2();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   aload_0
   5:   ldc     #2; //String onetwothree
   7:   putfield        #3; //Field s:Ljava/lang/String;
   10:  return
}

正如您所看到的,两个变量的处理方式相同。

我不认为这属于语言规范,因为这只是“编译器优化”。

一个不同的编译器(我使用的是Sun编译器)可能会做一些完全不同的事情 - 只要行为没有改变就可以了。

实际上,编译器已经在最新版本的Java中为您应用了该优化(至少从1.5开始,我认为)。

当Java Compiler在一行中看到许多String连接时会发生什么?

http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.18.1.2

只是常量字符串连接在编译时被优化,并且是微不足道的。 问题是当你做一些不那么微不足道的事情时:

String example1 =“Prefix”+ variableString1 +“Suffix”;

最糟糕的情况是循环,附加每个迭代需要创建一个新字符串。 因为这对缓冲的文件读取很常见,所以你可以重新创建非常大的字符串,这是我最近遇到的一个问题。

虽然我明白为什么你想要做你做的事情,代码的结构太不同了,只是插入和替换,编辑代码的脚本必须非常先进,以便能够处理所有的引用。 也许有一种方法可以使用自治内部类,但是可以让你保持相同的字符串引用,但是在字符串构建器中包含实际的构造。 它可能与优化器已经做的没什么不同

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM