当我编译此代码片段时。
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-最终变量:
基本类型或String类型的变量是最终变量,并使用编译时常量表达式(第15.28节)进行了初始化,该变量称为常量变量。
同样来自JLS§15.28-ConstantExpression:
使用String#intern()方法,始终将String类型的编译时常量表达式“ interned”,以便共享唯一的实例。
所以我知道str1和str2将在创建后立即被插入。“ str”和“ ing”将在行上共享相同的内存,String str= str1+str2;
但是str1 + str2如何在常量字符串池中直接产生“ string”。 没有调用任何String
Builder类,就像我不写时那样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
实际上,它也stringBuilder
用于串联。因此,它与final有关系。关于final
字符串,我绝对不知道有什么特别的地方吗?
http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28说
引用常量变量(第4.12.4节)的简单名称(第6.5.6.1节)是常量表达式。
http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28还说:
常量表达式是表示原始类型或String的值的表达式,该值不会突然完成,并且仅使用以下内容组成:
- 基本类型的文字和字符串类型的文字(§3.10.1,§3.10.2,§3.10.3,§3.10.4,§3.10.5)
- […]
- 加法运算符+和-(§15.18)
- […]
- 引用常量变量(第4.12.4节)的简单名称(第6.6.5.6.1节)。
示例15.28-1 常数表达式
[…]
“整数” + Long.MAX_VALUE +“很大。
由于这两个变量是常量表达式,因此编译器进行串联:
String str = str1 + str2;
编译方式与
String str = "str" + "ing";
编译方式与
String str = "string";
问题内容: 我使用来了解Java与运算符的工作方式。 它是用同样的操作? 问题答案: 不。使用和做不一样。 在Java中,字符串实例是不可变的。 因此,如果您这样做: 每次连接时都在创建新的字符串。 另一方面,StringBuilder就像一个缓冲区,可以在追加新Strings时根据需要增长。 经验法则是(由于我的评论而改变): 如果要进行大量连接(例如,在循环内进行连接,或生成由多个字符串连接的
问题内容: 嗨, 我正在尝试编写一个递归函数来计算Java中字符串的长度, 我知道已经存在str.length()函数,但是问题语句想要实现一个递归函数 在C编程语言中,终止字符为“ \ 0”,我只想知道如何知道字符串是否以Java结尾 当我在测试字符串中输入“ \ n”时,我的程序运行良好。请告诉我。谢谢! 输出: 问题答案: 请记住,此代码效率很低,但是它以递归方式计算String的长度。
如果您构建了一个对象,说“intruder”并将其定义为final,那么您仍然可以更改类定义中不是final的对象字段(即intruder.power=50;)。在这种情况下,限制将是关于入侵者的对象引用,而不是内部值。 我的问题是:字符串作为一个例子呢?如果您创建了一个字符串对象,比如“String s=new String(”str“);是否有一种方法可以更改字符串的”str“值?如果没有,为
问题内容: 我使用的是Oracle 10g,并具有以下表结构:id,段落 我想按ID分组并连接段落。每个段落可能超过1500个字符。 当我尝试wm_concat函数时,它抱怨字符串缓冲区太小。实际上,我在Oracle网站上尝试了许多示例,但所有示例均因字符串缓冲区太小而失败。 我该如何解决? 问题答案: 因此,我猜是错误的所在,我可以看到您在这种情况下如何认为这不适用于您。 但是,这是的错。这是一
问题内容: 如何在python中连接字符串? 例如: 将其与形成字符串: 问题答案: 最简单的方法是 但为了提高效率,请参阅:https : //waymoot.org/home/python_string/
我有一个对象,它在初始化时接受一个字符串来标识它的名称。 在上面的示例中,名称遵循一个约定,即整数与字符串“MyObject”连接在一起。一位同事抱怨说,由于int到字符串的转换,我编写这段代码的方式从性能角度来看其实很糟糕。这个数字是作为一个int接收的,我对此无能为力。object参数必须包含字符串。我怎么能让这更快?使用字符串格式会有帮助吗?