您的位置:首页 > 编程语言 > Java开发

JAVA学习 String类的并置的一个小问题

2018-02-06 01:01 337 查看
大半夜的手贱打开了VS管理器想装个.NET的库,结果更新了VS,然后就卡那导致没法睡觉。。。那就顺手来解决一个上课时候理解不是很清楚的字符串的并置中的一个小问题。

先来看课本上的代码

public class Example8_1{
public static void main(String args[]) {
String hello="你好";
String testOne="你"+"好";
System.out.println(hello==testOne); //输出结果是true
……
String you="你";
String hi="好";
String testTwo=you+hi;
System.out.println(hello==testTwo) //输出结果是false
String testThree=you+hi;
System.out.println(testTwo==testThree); //输出结果是false


在课本上看到这里时候我有些不明白,为什么第一次结果是true,后两次结果都是false。

经过查阅后,了解到JAVA中把String常量放入常量池中。常量池是JAVA为了避免频繁的创建和销毁对象而影响功能,实现了对象的共享。当我们对两个String类创建的对象进行”==”判断时,我们判断的是两个对象在常量池中的引用(也就是指向)的是不是同一个地方来比较的。

注:String类的equals经过重写后,功能与”==”不完全相同。它首先判断要比较的两个对象的地址是否相同(也就是”==”的功能)。当相同时候返回true;当不相同时,还要比较字符串中每个字符和它对应的字符是否一样。附上源码:

public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++]){
return false;
}
return true;
}
}
return false;
}


好了,回到我们课本上的例子。当我们第一次判断”hello==testOne”时候,因为testOne创建的”你”和”好”都只是字面量,所以他们加起来还是字面量,也就是并没有开辟一块新的空间,所以他在常量池中也还是指向已有的”你好”。

而我们第二次和第三次比较为什么是false呢?因为这时候我们”+”的两边已经是对象了,对于testTwo=you+hi来说,在运行时候是这样的:String testTwo=new StringBuilder().append(you).append(hi).toString();我们再来看看StringBuilder类中的toString()的源码:

public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}


从原码可以看出,toString返回的是一个new String(),也就是新开辟了一块空间,所以testTwo在常量池中指向的不是原有的”你好”,而是新开辟的空间。这也是为什么testThree和testTwo明明都是用you+hi生成缺依然不相等的原因了,因为testThree也有了新的一块空间。

这只是上课时候碰到的一个小问题,今晚顺手解决了,还有更多的问题等着去探索,未完待续
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java
相关文章推荐