Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中连接最终字符串?_Java_String_Final - Fatal编程技术网

如何在Java中连接最终字符串?

如何在Java中连接最终字符串?,java,string,final,Java,String,Final,当我编译这段代码时 public class InternTest { public static void main(String...strings ){ final String str1="str"; final String str2="ing"; String str= str1+str2; } } 它生成以下字节码 public static void main(java.lang.String...); f

当我编译这段代码时

public class InternTest {
    public static void main(String...strings ){
        final String str1="str";
        final String str2="ing";
        String str= str1+str2;

    }
}
它生成以下字节码

public static void main(java.lang.String...);
   flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
   Code:
     stack=1, locals=4, args_size=1
        0: ldc           #16                 // String str
        2: astore_1
        3: ldc           #18                 // String ing
        5: astore_2
        6: ldc           #20                 // String string
        8: astore_3
        9: return
所以字符串文字“string”已经存在于常量池中,该常量池在这一行的堆栈上被推送到
6:ldc#20//string string

引用JSL

根据JLS§4.12.4-最终变量:

原语类型或字符串类型的变量,即final和 使用编译时常量表达式(§15.28)初始化的 称为常量变量

同样来自JLS§15.28-恒久压力:

字符串类型的编译时常量表达式始终是“interned” 以便使用String#intern()方法共享唯一实例

所以我知道str1和str2在创建的那一刻就会被扣押。“str”和“ing”将在
String str=str1+str2行共享相同的内存
但是str1+str2如何在常量字符串池中直接生成“字符串”。没有像我不写
final
时那样调用任何字符串生成器类?看看是否和实习有关

我写了这个片段

public class IntermTest {
    public static void main(String...strings ){
         String str1=("str").intern();
        String str2=("ing").intern();
        String str= str1+str2;

    }
}
但是当我生成字节码时,我得到了这个

public static void main(java.lang.String...);
    flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
    Code:
      stack=3, locals=4, args_size=1
         0: ldc           #16                 // String str
         2: invokevirtual #18                 // Method java/lang/String.intern:
()Ljava/lang/String;
         5: astore_1
         6: ldc           #24                 // String ing
         8: invokevirtual #18                 // Method java/lang/String.intern:
()Ljava/lang/String;
        11: astore_2
        12: new           #26                 // class java/lang/StringBuilder
        15: dup
        16: aload_1
        17: invokestatic  #28                 // Method java/lang/String.valueOf
:(Ljava/lang/Object;)Ljava/lang/String;
        20: invokespecial #32                 // Method java/lang/StringBuilder.
"<init>":(Ljava/lang/String;)V
        23: aload_2
        24: invokevirtual #35                 // Method java/lang/StringBuilder.
append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        27: invokevirtual #39                 // Method java/lang/StringBuilder.
toString:()Ljava/lang/String;
        30: astore_3
        31: return
publicstaticvoidmain(java.lang.String…);
标志:ACC_PUBLIC、ACC_STATIC、ACC_VARARGS
代码:
堆栈=3,局部变量=4,参数大小=1
0:ldc#16//String str
2:invokevirtual#18//Method java/lang/String.intern:
()Ljava/lang/String;
5:astore_1
6:ldc#24//String-ing
8:invokevirtual#18//Method java/lang/String.intern:
()Ljava/lang/String;
11:astore_2
12:new#26//class java/lang/StringBuilder
15:dup
16:aload_1
17:invokestatic#28//方法java/lang/String.valueOf
:(Ljava/lang/Object;)Ljava/lang/String;
20:invokespecial#32//方法java/lang/StringBuilder。
“”:(Ljava/lang/String;)V
23:aload_2
24:invokevirtual#35//方法java/lang/StringBuilder。
追加:(Ljava/lang/String;)Ljava/lang/StringBuilder;
27:invokevirtual#39//方法java/lang/StringBuilder。
toString:()Ljava/lang/String;
30:astore_3
31:返回
实际上,它还使用
stringBuilder
进行连接。所以它和期末考试有关。
final
字符串是否有我绝对不知道的特殊之处

引用常量变量(§4.12.4)的简单名称(§6.5.6.1)是常量表达式

还说:

常量表达式是表示原语类型的值或字符串的表达式,该值或字符串不会突然完成,并且仅使用以下内容组成:

  • 基本类型的文字和字符串类型的文字(§3.10.1、§3.10.2、§3.10.3、§3.10.4、§3.10.5)
  • [……]
  • 加法运算符+和-(§15.18)
  • [……]
  • 引用常量变量(§4.12.4)的简单名称(§6.5.6.1)
例15.28-1。恒定表达式

[……]

整数“+Long.MAX_VALUE+”非常大

由于这两个变量是常量表达式,编译器将进行串联:

String str = str1 + str2;
编译方式与

String str = "str" + "ing";
String str = "string";
它的编译方式与

String str = "str" + "ing";
String str = "string";

如果编译器这样做,为什么它仍然隐藏在字节码中,或者它在其他地方这样做,因为如果我没有错,现代Java编译器会通过
StringBuilder的append来转换我的+操作。
?正如我所说,连接是由编译器本身完成的,而不是在运行时完成的。为行
String str=str1+str2
生成的字节码与为行
String str=“String”
生成的字节码完全相同,因为
str1+str2
是一个常量表达式。“因为str1+str2是一个常量表达式”或者更准确地说,因为str1和str2不仅仅是常数,但编译时常数允许编译器计算一次,并将结果放入代码中,而不是每次执行此代码时在运行时重新计算。有消息告诉我,这将是您下一个问题的答案:@Pshemo,当这变得清晰时..我认为这不会导致任何问题。。无论如何,谢谢你提出这么好的问题:)每个问题都是很棒的学习曲线!