+;Java中字符串的运算符
几分钟前我看到了,并决定查看一下java字符串类,以检查+;Java中字符串的运算符,java,string,operator-overloading,string-concatenation,Java,String,Operator Overloading,String Concatenation,几分钟前我看到了,并决定查看一下java字符串类,以检查+操作符是否有一些重载 我什么也找不到,但我知道我能做到 String ab = "ab"; String cd = "cd"; String both = ab + cd; //both = "abcd" 在哪里实现的?它由编译器处理。来自: Java语言为字符串连接运算符(+)以及其他对象到字符串的转换提供了特殊支持。字符串连接是通过StringBuilder(或StringBuffer)类及其append方法实现的。字符串转换是通过
+
操作符是否有一些重载
我什么也找不到,但我知道我能做到
String ab = "ab";
String cd = "cd";
String both = ab + cd; //both = "abcd"
在哪里实现的?它由编译器处理。来自: Java语言为字符串连接运算符(+)以及其他对象到字符串的转换提供了特殊支持。字符串连接是通过
StringBuilder
(或StringBuffer
)类及其append
方法实现的。字符串转换是通过toString方法实现的,该方法由Object定义并由Java中的所有类继承。有关字符串连接和转换的更多信息,请参阅Gosling、Joy和Steele,Java语言规范
请参见JLS中的。这是在语言级别完成的。Java语言规范是。这是中记录的特殊行为 15.18.1字符串连接运算符+ 如果只有一个操作数表达式为 输入String,然后进行字符串转换 对要删除的另一个操作数执行 在运行时生成字符串。这个 结果是对字符串的引用 对象(新创建的,除非 表达式是编译时常量 表达式(§15.28)),即 两个操作数的并置 串。这本书的特点 左操作数位于 右操作数的字符 在新创建的字符串中。如果 字符串类型的操作数为null,则 使用字符串“null”代替 那个操作数
编译器将您的代码视为您编写了以下内容:
String both = new StringBuilder().append(ab).append(cd).toString();
"a"+"b"+"c"
编辑:有参考资料吗?如果我编译和反编译OP的代码,我会得到:
0: ldc #2; //String ab
2: astore_1
3: ldc #3; //String cd
5: astore_2
6: new #4; //class java/lang/StringBuilder
9: dup
10: invokespecial #5; //Method java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: return
0:ldc#2//字符串ab
2:astore_1
3:最不发达国家3//字符串cd
5:astore_2
6:新#4//类java/lang/StringBuilder
9:dup
10:特别是#5//方法java/lang/StringBuilder。“”:()V
13:aload_1
14:invokevirtual#6//方法java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17:aload_2
18:invokevirtual#6//方法java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21:invokevirtual#7//方法java/lang/StringBuilder.toString:()Ljava/lang/String;
24:astore_3
25:返回
就像我说的。
String
被定义为标准类型,就像编译器级别的int、double、float等。本质上,所有编译器都有运算符重载。操作符重载不是为开发人员定义的(与C++不同)
有趣的是:这个问题被记录为一个bug:这里的大多数答案都是正确的(由编译器处理,+被转换为.append()…) 我想补充一点,每个人都应该看看String和append的源代码,这非常令人印象深刻 我相信这可以归结为:
String both = new StringBuilder().append(ab).append(cd).toString();
"a"+"b"+"c"
=
但随后一些神奇的事情发生了。这就变成了:
- 创建长度为3的字符串数组
- 将a复制到第一个位置
- 将b复制到第二个
- 将c复制到第三个
现在我只是感到困惑。阅读源代码——它相当酷。令人印象深刻的答案。你考虑过当老师吗?@Willi Schönborn:嗯,这是一个简单而正确的答案。当我写的时候,我没有时间写更多,当我回到电脑前,有很多答案更详细地解释了它。很抱歉,但我不认为复制其他答案有什么意义,如果你需要更多信息,我建议你阅读@Sean's和@jleedev's(是的,我的简历上有教学内容)。重点是:你的答案非常笼统,几乎可以回答约75%与java相关的问题。@Will Schönborn 75%的java问题都不是由编译器处理的。事实上,在大多数情况下,编译器只是将源代码编译成字节码。少数例外是字符串上的+运算符,以及一些结果是内在函数内联的情况。我的答案是第一个,唯一的目的是快速回答,在等待更完整的答案的同时,指出OP的正确方向。在开会之前,我有大约30秒的空闲时间,并将它们奉献给大家。如果您不喜欢,请访问hyphen网站或其他网站,或亲自构建一些代表,而不要抱怨。
StringBuilder
如果不需要同步,则应首选。@gpampara编译器知道如何使用StringBuilder。StringBuffer在引入StringBuilder之前在旧版本中使用。没有新字符串().append(“a”).append(“b”).append(“c”)
,而是新的StringBuilder().append(“a”).append(“b”).append(“c”).toString()
。没有StringBuilder的方式是a.concat(“b”).concat(“c”)
,正如您所描述的,这是一种低效的方法。(但是,当将+与编译时常量一起使用时,所有这些都已由编译器完成。)