Java是一种强类型语言。因此,编译代码中的错误更少,编码速度更慢,可读性更高。因此,需要显式类型转换,这部分是清楚的。
这些片段之间有什么区别:
(String)myInt // obviously doesn't compile
Integer.toString(myInt)
"" + myInt
这纯粹是出于历史原因,还是背后有一些含义? 哪种方法合适?
答案 0 :(得分:5)
如前所述,(String) myInt
是一种类型转换。您可以在对象层次中在基元内或向上投射。由于int
是基元,String
是对象,因此我们遇到了问题。即使Autoboxing无法解决这种困境,因为Integer
和String
并不代表继承关系。因此,(String) myInt
导致编译错误是完全合理的。
Integer.toString(myInt)
和"" + myInt
的语义相同。然而,细节是不同的。
执行Integer.toString(myInt)
时,会构造一个新的String
,其中包含myInt
的字符串表示。
执行"" + myInt
时,首先构造一个全局String
- 常量,其值为""
(这是由JVM完成的,你看不到这个 1 < / SUP>)。词法分析器在String
的右侧需要+
,因为它找到了String
左侧的+
。对于原语,JVM&#34;知道&#34;如何将它们转换为String
s。对于对象,调用toString()
。由于Object
具有此方法,并且每个类(至少是隐式)派生自Object
,因此每个对象都保证具有toString()
方法。这是构建的第二个String
。从String
s are immutable开始,JVM可能会创建第三个String
,表示前两个String
s 2 的串联。
尾声:
然后,在执行时,JIT编译器会发生冲击,并且大多数情况可能无关紧要,因为两种变体的JIT优化版本可能看起来相同。或不。或者可能只是有时候。 JIT做有趣的事情。所以最后它更多的是个人风格而不是表现的问题:)
1 这实际上是一个谎言。写作时
String s1 = "";
String s2 = "";
System.out.println(s1 == s2);
人们会发现结果是true
,而false
是预期的。这是因为JVM为所有String
常量创建了一个池来节省一些内存。
2 很有可能JVM&#34;识别&#34; something + "" == "" + something == something
,因此不会创建第三个String
。我既没有测试也没有研究过这个。
答案 1 :(得分:4)
我倾向于选择String.valueOf(int)
,我自己,但是有多条路可以到达那里。
一般情况下,如果您要将int
转换为String
隔离,则需要Integer.toString(int)
,String.valueOf(int)
,或类似的。
您的"" + myInt
效率明显低于上述效果(虽然通常无关紧要):它会编译为创建新的StringBuilder
,然后将""
附加到其中,然后将int
附加到它(它调用上述方法之一将其首先转换为字符串),然后从String
获取StringBuilder
。因此,虽然您可以将其作为整体连接操作的一部分,但它本身很差。
您的(String)
示例无效:您无法将int
投射到String
,您将获得编译时间& #34;不兼容的类型&#34;错误。
答案 2 :(得分:3)
这是一种正式的语言功能&#34;重载"" + myInt
运算符,使
new StringBuilder().append("").append(myInt).toString();
编译就像是:
StringBuilder#append()
和String.valueOf()
(最终)调用myInt
来呈现{{1}}。
这个功能大概是因为如果他们没有,没有人会使用这种语言 - 那就太痛苦了。
答案 3 :(得分:2)
(String)
- 这只适用于字符串,所以如果你有这个:
Object test = "test";
String test2 = (String) test;
它会起作用(因为Object
测试将是String
类型)。
如果你有这样的事情:
Integer test = new Integer(2);
String test2 = (String) test;
你得到ClassCastException
。
Integer.toString(myInt)
这就是它的作用:
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
getChars(i, size, buf);
return new String(0, size, buf);
}
它只是通过char将你的号码变成字符串char。
"" + myInt
这将告诉编译器你想要将字符串连接起来,而不是添加两个数字(因为字符串是第一个,它将与连接字符串一起使用)。 myInt将变为字符串,或者如果它是一个对象,它将从中调用toString()
方法。
另外,请务必阅读JVM中的字符串池,了解它将在此处执行的操作。在这种情况下,最终可能会创建大量临时字符串(如果您有很多+
;请使用StringBuilder
来避免这种情况。)
答案 4 :(得分:2)
首先,让我们比较(String)val
和val.toString()
。
这两个陈述的主要区别在于,编译器进行强制转换,而toString()
方法通常由程序员实施。也就是说,只有在值String
延伸且您可以实现任何类的toString()
时才能进行强制转换。 toString()
就像任何其他方法一样,没有任何(几乎)特别的方法。
现在让我们来看看""+int
。我个人认为这是反模式,因为它被编译成非常低效的代码。创建了许多无用的对象;简而言之:结果类似于手动连接几个字符串文字与StringBuilder
。此外,在""+var
var
这样的语句中,String
不会扩展toString()
,而是隐式调用 public static void main(String[] args) {
int i= (int) getValue(10,int.class);
System.out.println("int value -->"+i);
Double d = (Double) getValue(25.023,double.class);
System.out.println("double d-->"+d);
String s=(String) getValue("adf",String.class);
System.out.println("String s-->"+s);
}
public static <T> Object getValue(Object obj,Class<?> type) {
return obj;
}
。
我希望这很清楚。