1、String 是一个特殊的包装类数据。
(1)可以用 String str = new String("abc");的形式来创建;
(2)也可以用String str = "abc"的形式来创建。
第一种创建方式,和普通对象的创建过程一样;
第二种创建方式,Java内部将此语句转换为以下步骤:
先定义一个名为str的String类的对象引用变量:String str;
在栈中查找有没有存放值为“abc”的地址,如果没有,则开一个存放字面值为“abc”的地址;如果有一个String类型的对象o,并将o的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为“abc”的地址,则查找对象o,并返回o的地址。
将str指向对象o的地址。
值得注意的是,一般String类中字符串值都是直接存值的。但像String str="abc";这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用。
2、为了更好的说明这个问题,我们可以通过以下的几个代码进行验证。
String str1 = "abc";
String str2 ="abc";
System.out.println(str1 == str2);//返回结果true
System.out.println(str1.equals(str2));//返回结果true
==号,根据JDK的说明,只有在两个引用都指向了同一个对象时才返回真值,即比较地址。
equals是比较两个对象的值是否相等,相等返回true,不相等返回false。综上来看,这两个对象的值都是“abc”,所以相等。
代码如下:
package com.ruoyi.common.core.text;
public class Test {
public static void main(String[] args) {
String str1="abc";
String str2="abc";
//比较地址相等
System.out.println((str1==str2));
//equals是比较值相等
System.out.println(str1.equals(str2));
}
}
运行结果如下:
3、再接着看以下代码
String str1 = new String("abc");
String str2 = "abc";
System.out.println(str1 == str2);//返回结果
System.out.println(str1.equals.str2);//返回结果
代码如下:
package com.ruoyi.common.core.text;
public class Test {
public static void main(String[] args) {
//用new的方式是生成不同的对象,每一次调用都生成一个新的对象。
String str1 = new String("abc");
String str2="abc";
//比较地址相等
System.out.println((str1==str2));
//equals是比较值相等
System.out.println(str1.equals(str2));
}
}
运行结果如下:
第一种方式String str1 = new String("abc")创建了两个对象,一个是静态区的值“abc”,一个是用new创建在堆上的对象。这种方式每调用一次就会创建一个新的对象。
第二种是先在栈中创建一个堆String类的对象引用变量str,然后查找栈中有没有存放“abc”,如果没有,则将“abc”存放进栈,并令str指向“abc”;如果已经有“abc”,则直接令str指向“abc”。
简单来说:
比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时用==