隐式转换为字符串 – toString和int +“”
为什么当我使用它:
int a = 1; methodWithParamString(a + "");
a被强制转换为String,我不能在整数上使用toString()吗?
int a = 1; methodWithParamString(a.toString());
这不是: a+""
作用类似于: a.toString() + ""
?
不,它的工作方式类似于String.valueOf( a ) + ""
,它反过来表现得像new StringBuilder( String.valueOf( a ) ).append( "" ).toString()
。
重要的是要知道它完全由编译器完成,换句话说就是它的语法糖。 这就是为什么在循环中将字符串组合在一起并不是一个好主意。 (尽管现代VM可能有一些机制来降低性能开销。)
a被强制转换为String
不会。它被转换为String。 (您无法隐式或显式地将基本类型转换为String。)
此转换的详细信息在JLS- 15.18.1.1中指定。 该规范声明,对于基本类型,转换“就像”您创建了适当的包装类型的实例,然后在其上调用toString()
。 这使得Java编译器可以选择使用其他方法,只要最终结果相同。 (对于引用类型,转换通过调用toString()
将null
转换为"null"
,将其他非String类型转换为String。)
JLS声明通过调用String.concat(...)
“然后”执行连接,注意JLS明确允许优化连接序列。 (JLS 15.18.1.2 )
这不是:a +“”的作用类似于:a.toString()+“”?
真正。 它没有。
+
在内部超载。 和Java不支持对基元的方法调用。
因为int a – 不是对象,所以它是原始类型。 所以它没有任何方法。 你应该使用拳击:
Integer objectA = new Integer(a); objectA.toString();
toString()
是Object
类中的一个方法,任何从它inheritance的类都将具有该方法,如Integer
或String
。 但int
是基本类型而不是Object,因此该方法不存在。
不int
是原始类型,所以它不是一个对象,不能有任何方法。
阅读本文我认为这将有所帮助。 有基元的包装类,例如int
Integer
。 您可以为它们调用toString()
方法。
实际上String
是java中的一个特殊类。 并且您可以对字符串和基元使用+(而不仅仅是)运算符。 我想你会在这里找到你问题的完整答案。
在Java中实现这一点的方式实际上比其他答案似乎更简单。
将字符串连接运算符与String和对象一起使用会导致调用该对象的toString()
方法,然后执行字符串连接。
请记住,只要将原语传递给Object有效的上下文,Java就会执行“autoboxing”,将int
转换为Integer
,将double
转换为Double
,等等。
因此,您可以将其视为自动装箱,然后是toString(),后跟字符串连接。
同时,您应该意识到JLS字符串连接规范允许JVM实现优化自动装箱,只要结果相同,因此您的JVM可以使用StringBuilder,或使用任何其他有效的JVM字节码来创建结果字符串,所以字符串连接运算符的性能往往比自己执行拳击更好。