【发布时间】:2023-03-24 07:15:01
【问题描述】:
为什么当我使用这个时:
int a = 1;
methodWithParamString(a + "");
a 被转换为字符串,但我不能在整数上使用 toString()?
int a = 1;
methodWithParamString(a.toString());
这不是:a+"" 像:a.toString() + "" 一样工作吗?
【问题讨论】:
为什么当我使用这个时:
int a = 1;
methodWithParamString(a + "");
a 被转换为字符串,但我不能在整数上使用 toString()?
int a = 1;
methodWithParamString(a.toString());
这不是:a+"" 像:a.toString() + "" 一样工作吗?
【问题讨论】:
不,它的工作方式类似于 String.valueOf( a ) + "",而其行为又类似于 new StringBuilder( String.valueOf( a ) ).append( "" ).toString()。
重要的是要知道这一切都是由编译器完成的,换句话说,它是语法糖。这就是为什么在一个循环中添加字符串不是一个好主意的原因。 (尽管现代虚拟机可能有一些机制来降低性能开销。)
【讨论】:
String.valueOf(a) 只是调用Integer.toString(a)
a 被转换为字符串
没有。它被转换为字符串。 (不能隐式或显式地将原始类型转换为字符串。)
此转换的详细信息在 JLS - 15.18.1.1 中指定。规范指出,对于原始类型,转换是“好像”您创建了适当包装类型的实例然后在其上调用 toString() 一样。这使得 Java 编译器可以选择使用其他方法,前提是最终结果相同。 (对于引用类型,通过调用toString(),转换将null 转换为"null" 和其他非String 类型转换为String。)
JLS 声明然后通过调用String.concat(...)“好像”执行连接,并指出 JLS 明确允许优化连接序列。 (JLS15.18.1.2)
【讨论】:
这不是:a+"" 的工作方式类似于:a.toString() + "" 吗?
没错。它没有。
+ 内部过载。并且 Java 不支持对原语进行方法调用。
【讨论】:
在 Java 中实现这一点的方式实际上比其他答案似乎暗示的要简单一些。
对字符串和对象使用字符串连接运算符会导致调用该对象的toString() 方法,然后执行字符串连接。
请记住,只要将原语传递给对象有效的上下文,Java 就会执行“自动装箱”,将int 转换为Integer,将double 转换为Double,等等。
因此您可以将其视为自动装箱,然后是 toString(),然后是字符串连接。
同时,您应该意识到JLS string concatenation spec 允许 JVM 实现优化掉自动装箱,前提是结果相同,因此您的 JVM 可以改用 StringBuilder,或使用任何其他有效的 JVM 字节码来创建结果字符串,因此字符串连接运算符的性能通常比自己执行装箱要好。
【讨论】:
因为 int a - 不是对象,它是原始类型。 所以它没有任何方法。 你应该使用拳击:
Integer objectA = new Integer(a);
objectA.toString();
【讨论】:
new Integer(a),其中 a 是一个 int。您应该依赖自动装箱或使用 Integer.valueOf(a),因为 Java 在内部缓存 Integer 等原语的实例化,从而避免创建不必要的实例。
toString() 是Object 类中的一个方法,任何继承自它的类都会有该方法,例如Integer 或String。但是int是原始类型而不是Object,所以该方法不存在。
【讨论】: