Poo*_*oya 127 java string object
为什么在Java中,当String是一个类时,你能用+运算符添加字符串?在String.java
代码中我没有找到该运算符的任何实现.这个概念是否违反了面向对象?
Lio*_*ion 155
让我们看看Java中的以下简单表达式
int x=15;
String temp="x = "+x;
Run Code Online (Sandbox Code Playgroud)
编译器"x = "+x;
在StringBuilder
内部转换为内部并用于.append(int)
将整数"添加"到字符串.
可以通过字符串转换将任何类型转换为String类型.
首先将基本类型T的值x转换为引用值,就好像将它作为参数提供给适当的类实例创建表达式(第15.9节):
- 如果T是布尔值,则使用new Boolean(x).
- 如果T是char,则使用new Character(x).
- 如果T是byte,short或int,则使用new Integer(x).
- 如果T很长,则使用新的Long(x).
- 如果T是float,则使用new Float(x).
- 如果T为double,则使用new Double(x).
然后通过字符串转换将此引用值转换为String类型.
现在只需要考虑参考值:
- 如果引用为null,则将其转换为字符串"null"(四个ASCII字符n,u,l,l).
- 否则,执行转换就好像通过调用没有参数的引用对象的toString方法一样; 但是如果调用toString方法的结果为null,则使用字符串"null".
toString方法由原始类Object(第4.3.2节)定义.许多类都覆盖它,特别是Boolean,Character,Integer,Long,Float,Double和String.
有关字符串转换上下文的详细信息,请参见第5.4节.
字符串连接的优化: 实现可以选择在一个步骤中执行转换和连接,以避免创建然后丢弃中间String对象.为了提高重复字符串连接的性能,Java编译器可以使用StringBuffer类或类似技术来减少通过计算表达式创建的中间String对象的数量.
对于基本类型,实现还可以通过直接从基本类型转换为字符串来优化包装对象的创建.
优化版本实际上不会首先执行完全包装的String转换.
这是编译器使用的优化版本的一个很好的例证,虽然没有原语的转换,你可以看到编译器在后台将事物更改为StringBuilder:
http://caprazzi.net/posts/java-bytecode-string-concatenation-and-stringbuilder/
这个java代码:
public static void main(String[] args) {
String cip = "cip";
String ciop = "ciop";
String plus = cip + ciop;
String build = new StringBuilder(cip).append(ciop).toString();
}
Run Code Online (Sandbox Code Playgroud)
生成这个 - 看看两个连接样式如何导致相同的字节码:
L0
LINENUMBER 23 L0
LDC "cip"
ASTORE 1
L1
LINENUMBER 24 L1
LDC "ciop"
ASTORE 2
// cip + ciop
L2
LINENUMBER 25 L2
NEW java/lang/StringBuilder
DUP
ALOAD 1
INVOKESTATIC java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String;
INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;
ASTORE 3
// new StringBuilder(cip).append(ciop).toString()
L3
LINENUMBER 26 L3
NEW java/lang/StringBuilder
DUP
ALOAD 1
INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;
ASTORE 4
L4
LINENUMBER 27 L4
RETURN
Run Code Online (Sandbox Code Playgroud)
查看上面的示例以及如何生成基于给定示例中的源代码的字节代码,您将能够注意到编译器已在内部转换了以下语句
cip+ciop;
Run Code Online (Sandbox Code Playgroud)
成
new StringBuilder(cip).append(ciop).toString();
Run Code Online (Sandbox Code Playgroud)
换句话说,+
字符串连接中的运算符实际上是更详细的StringBuilder
习语的简写.
Ram*_*PVK 27
它是Java编译器功能,它检查运算+
符的操作数.并根据操作数生成字节码:
这就是Java规范所说的:
运算符+和
-
称为加法运算符.AdditiveExpression:MultiplicativeExpression AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression加法运算符具有相同的优先级,并且在语法上是左关联的(它们从左到右分组).如果
+
运算符的任一操作数的类型是String
,则操作是字符串连接.否则,运算
+
符的每个操作数的类型必须是可转换(第5.1.8节)到原始数字类型的类型,否则会发生编译时错误.在每种情况下,二元
-
运算符的每个操作数的类型必须是可转换(第5.1.8节)到原始数字类型的类型,否则会发生编译时错误.
首先(+)重载不被覆盖
Java语言为字符串连接运算符(+)提供了特殊支持,该运算符已针对Java Strings对象进行了重载.
如果左侧操作数是String,则它作为串联工作.
如果左侧操作数是Integer,则它作为加法运算符
归档时间: |
|
查看次数: |
30498 次 |
最近记录: |