下午好
许多人都知道,
Java使用这样的设计是不可取的。
"Hello" + "Name" + "Surname" + etc.;
//или же
String text = "Hello";
text += "Name";
text += "Surname";
text += etc...;
在这些情况下值得使用StringBuilder,虽然我对此有疑问,但我想知道我是否正确使用它?
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Name: " + this.getName());
builder.append("\nSurname: " + this.getSurname());
builder.append("\nAge: " + this.getAge());
builder.append(this.isSex() ? "\nWoman " : "\nMan ");
builder.append("\nCourse: " + this.course);
builder.append("\nFaculty: " + this.faculty);
builder.append("\nGroup: " + this.group);
String result = new String(builder);
return result;
}
查看代码,我认为我使用不正确......如果是这样,请告诉我它应该如何,以及在这种情况下使用什么是可取的?
将 append 中的串联操作替换为对 append 自身的调用链的延续,以最大限度地减少 String 类型的新字符串的创建:
等等 总的来说-一切都很好。是的,这种情况下的优化问题值得怀疑,尽管不排除...
第二个块(直接用你的代码)已经被拆除。
事实上,
+如果这些是普通字段,而不是使用某些方法调用,则可以通过 连接字符串side-effect'ами。编译器足够聪明,可以用java.lang.StringBuilder.您可以通过考虑以下示例来验证这一点:
让我们看看生成了什么字节码。你不能深入细节,这里最重要的是对它的解释。
公开课 en.izebit.Man 次要版本:0 主要版本:52 标志:ACC_PUBLIC、ACC_SUPER 常量池: #1 = Methodref #9.#25 // java/lang/Object."":()V #2 = 类 #26 // java/lang/StringBuilder #3 = Methodref #2.#25 // java/lang/StringBuilder."":()V #4 = Fieldref #8.#27 // ru/izebit/Man.name:Ljava/lang/String; #5 = Methodref #2.#28 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #6 = Fieldref #8.#29 // ru/izebit/Man.surname:Ljava/lang/String; #7 = Methodref #2.#30 // java/lang/StringBuilder.toString:()Ljava/lang/String; #8 = Class #31 // ru/izebit/Man #9 = 类 #32 // java/lang/对象 #10 = Utf8 名称 #11 = Utf8 Ljava/语言/字符串; #12 = Utf8 姓氏 #13 = utf8 #14 = Utf8()V #15 = Utf8 代码 #16 = Utf8 行号表 #17 = Utf8 本地变量表 #18 = Utf8 这个 #19 = Utf8 Lru/izebit/Man; #20 = Utf8 优先方法 #21 = Utf8()Ljava/lang/String; #22 = Utf8 secondMethod #23 = Utf8 源文件 #24 = Utf8 Man.java #25 = NameAndType #13:#14 // "":()V #26 = Utf8 java/lang/StringBuilder #27 = NameAndType #10:#11 // 名称:Ljava/lang/String; #28 = NameAndType #33:#34 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #29 = NameAndType #12:#11 // 姓氏:Ljava/lang/String; #30 = NameAndType #35:#21 // toString:()Ljava/lang/String; #31 = Utf8 ru/izebit/Man #32 = Utf8java/语言/对象 #33 = Utf8 追加 #34 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder; #35 = Utf8 转字符串 { 公共 ru.izebit.Man(); 描述符:()V 标志:ACC_PUBLIC 代码: 堆栈=1,本地=1,args_size=1 0:加载_0 1: invokespecial #1 // 方法 java/lang/Object."":()V 4:返回 行号表: 第 4 行:0 局部变量表: 起始长度 槽名 签名 0 5 0 这个 Lru/izebit/Man; public java.lang.String firstMethod(); 描述符:()Ljava/lang/String; 标志:ACC_PUBLIC 代码: 堆栈=2,本地=1,args_size=1 0: new #2 // 类 java/lang/StringBuilder 3:重复 4: invokespecial #3 // 方法 java/lang/StringBuilder."":()V 7:加载_0 8: getfield #4 // 字段名:Ljava/lang/String; 11: invokevirtual #5 // 方法 java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 14:加载_0 15: getfield #6 // 字段姓氏:Ljava/lang/String; 18: invokevirtual #5 // 方法 java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 21: invokevirtual #7 // 方法 java/lang/StringBuilder.toString:()Ljava/lang/String; 24:转 行号表: 第 9 行:0 局部变量表: 起始长度 槽名 签名 0 25 0 这个 Lru/izebit/Man; 公共 java.lang.String secondMethod(); 描述符:()Ljava/lang/String; 标志:ACC_PUBLIC 代码: 堆栈=2,本地=1,args_size=1 0: new #2 // 类 java/lang/StringBuilder 3:重复 4: invokespecial #3 // 方法 java/lang/StringBuilder."":()V 7:加载_0 8: getfield #4 // 字段名:Ljava/lang/String; 11: invokevirtual #5 // 方法 java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 14:加载_0 15: getfield #6 // 字段姓氏:Ljava/lang/String; 18: invokevirtual #5 // 方法 java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 21: invokevirtual #7 // 方法 java/lang/StringBuilder.toString:()Ljava/lang/String; 24:转 行号表: 第 13:0 行 第 14:11 行 第 15:18 行 第 16:21 行 第 13:24 行 局部变量表: 起始长度 槽名 签名 0 25 0 这个 Lru/izebit/Man; }正如我们所见,这两种方法都使用
java.lang.StringBuilder.关于您的代码,除了过于冗长之外,它是非常正确的。
StringBuilder允许您使用更简洁地编写fluent style是的,该方法
StringBuilder.append()将返回instanceStringBuilder,也就是说,您可以按照 'ep1demic' 的指示进行操作最好不要使用
this.getSurname(),而只是写而
sb.getString();不是new String(sb);