这是我从未真正理解过的Java。让我们说:
int x = 4;
现在我不能这样做
functionThatRequiresString(x)
或functionThatRequiresString((String)x)
现在我无法传递一个需要字符串变量x
的函数。我也无法将它从int转换为字符串。现在正常的做法是:
Integer.toString(x)
或String.valueOf(x)
现在我为什么要这样做?
functionThatRequiresString(""+x)
这与将整数转换为字符串有何不同?
答案 0 :(得分:3)
转换意味着你告诉编译器“我在这里有一个类型A的对象,但是我希望你把它当作类型B对待它。不要给出错误,因为它看起来不像B给你“。
Casting不进行任何转换(至少不适用于非基本类型)。如果在运行程序时,该对象确实不是B类,那么您将获得ClassCastException
。
您无法将int
转换为String
因为int
根本不是String
- 您可以告诉编译器假装它是,但是你'运行程序时会得到ClassCastException
。
您提供的其他示例将转换(而非强制转换)int
转换为String
。
答案 1 :(得分:3)
为了完整起见,我们可以查看编译后的字节代码:
int i = 1;
String s1 = "" + i;
String s2 = Integer.toString(i);
使用JDK 1.5.0_16(古代我知道,但我认为新的JDK不会有所不同),将编译为:
0: iconst_1
1: istore_1
2: new #2; //class java/lang/StringBuilder
5: dup
6: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
9: ldc #4; //String
11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: iload_1
15: invokevirtual #6; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
18: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
21: astore_2
22: iload_1
23: invokestatic #8; //Method java/lang/Integer.toString:(I)Ljava/lang/String;
26: astore_3
因此,当您使用s1 = "" + i"
时,您实际在做的是:
s1 = new StringBuilder().append("").append(i).toString();
(创建一个新对象并调用append(String)
,然后调用append(int)
的{{1}}方法,然后将其转换为字符串。
所以像StringBuilder
这样的人更有效......
答案 2 :(得分:2)
Casting具有特定含义,即更改引用的类型,但不更改引用对象的类型或内容。
""+x
有一个特定的用例,只与字符串有关。您无法通过这种方式转换为任何其他数据类型。
Java并没有&#34; cast&#34;从一种物体到另一种物体。
答案 3 :(得分:1)
在Java中无法将int转换为String。在表达式中:
functionThatRequiresString(""+x)
没有转换,如果其中一个参数是String,则调用+运算符返回String。
答案 4 :(得分:1)
简短的回答是,您不能强制 int
到String
,因为String
不是int
的父类或子类}}。转换是关于如何在不同的相关类中查看对象。
你真正要问的是(我认为)为什么Java不能在你的类型之间自动转换?
答案和你不能做functionThatRequiresString(x)
的原因是因为Java是type safe并且坚持要将值正确的类型传递给方法。这样做的好处是你不会很难找到你将错误类型传递给函数的错误,但是它会被静默地转换为正确的类型,所以你编写代码但运行时非常奇怪。正如您所见,缺点是当您想要执行转换时不太方便。
为什么可以执行像"" + x
这样的事情的原因是因为这是编译器为您处理所有转换的常见操作。当您在此处明确创建字符串时,可以安全地进行转换。