package string;
public class Example1 {
public static void main(String[] args) {
String str;
double n = 18;
double m = 2;
str = n + "+" + m;
System.out.println(str);
}
}
在上述代码中,str是怎么把m和n转换为String的?
可以看一下关于类型转换,数值类型+字符串 会先把数值转换为字符串再进行连接。。。
和编译器有关!本人猜测,首先编译器new n m两个double对象,然后new str时将double转为string,然后编译器处理为stringbuilder连接
tostring方法
String.valueOf()
java 所有数据都是类对象
double 有 tosting 方法
所以 每个内部类型 都可以自动转换成字符串只要需要
哪怕是常数也可以
java 所有数据都是类对象
double 有 tosting 方法
所以 每个内部类型 都可以自动转换成字符串只要需要
哪怕是常数也可以
java 所有数据都是类对象
double 有 tosting 方法
所以 每个内部类型 都可以自动转换成字符串只要需要
哪怕是常数也可以
我觉得是先将double类型自动装箱为Double类型,然后调用Double类型的toString方法。
这样就可以了:
public static void main(String[] args) {
String str = "";
double n = 18;
double m = 2;
str = String.valueOf(n) +" "+ String.valueOf(m);
System.out.println(str);
}
关于猜测是否是"先封装为基本类型再调用toString方法",特予以验证,结果是否定的。这一点可以通过高版本jdk下执行如下代码获得验证。
之所以强调高版本,并且使用int类型而不是double类型,是因为jdk对int类型的Integer.valueOf()方法提供了缓存,而低版本,或者double类型则没有对应的缓存,无法采用此方法予以验证。
//预注册一个变量i,避免在编译期就计算出""+1的值
int i = 1;
Field f = Integer.class.getDeclaredField("value");
f.setAccessible(true);
f.set(1, 0);
System.out.println(Integer.valueOf(1));
// 此时,封装类型值为1的情况,已经被强行修改为0
System.out.println(""+i);
// 然而,""+1的结果仍然是1
由于String.valueOf()方法不缓存,因此@小小村 的思路同样无法通过此方法予以验证,不过这个思路与其它回答中@u012335961 提到的Integer.toString(11)思路异曲同工。
不过还有一种可能,在jdk高版本中提供了一种优化方法,即将连续的加法转化为new StringBuilder().append().append()...;
然而从语法的角度来思考,int+String更接近于C语言的"算符重载",有可能Java内部机制提供了一个重载机制,没有对我们公开而已。
大致存在以上几种可能吧。
String的加法有重载,遇到别的类型,会调用toString。没那么复杂。
public static void main(String[] args) {
String str = "";
double n = 18;
double m = 2;
//第一种方法,使用toString(),不能直接m.toString(),会报错,
//可以把m 强转为Double后,再使用toString()
System.out.println(((Double)m).toString()+“”+((Double)n).toString());
//第二种方法是使用 String.valueOf(m),把m直接转为String,
//推荐这个方式。
str = String.valueOf(n) +""+ String.valueOf(m);
System.out.println(str);
}
本人已测试通过!!!
首先double是基本数据类型,是没有什么toString方法的,代码中的类型转换并没有调用任何方法,出现此种结果是由字符串的特性和编译器的优化决定的。可以反编译对应的class文件,发现在程序执行之前str的值就已经固定了,为18+2。因为m,n,str会被编译器解释成final类型的,所以程序执行前值就知道了,此种计算编译器完全可以完成,虚拟机不必浪费资源进行计算。
上面的回答中编译后的文件内容有误,抱歉。现更正如下:
首先double是基本数据类型,是没有什么toString方法的,出现此种结果是由字符串的特性决定的。在Java中字符串支持“+”运算符,该运算符对字符串的运行结果是将所有的内容以字面值的形式拼接起来,所以会出现18.0+2.0的结果。18.0和2.0是编译器处理后的n与m的值。
看一下反编译的内容:
红色圈起来的地方说明在代码中调用了StringBuilder类的append()方法和toString()方法。
对于原先的错误回答,请各位见谅。
流弊,都深入到编译器级别啦,学习啦