String类是引用数据类型,其创建对象的方式有两种:
- 直接赋值
public class StringLearn { //创建类
public static void main(String[] args) {
String name = "yjt"; //直接赋值
System.out.println(name); //输出 “yjt”
}
}
- new 构造方法
public class StringLearn { //创建类
public static void main(String[] args) {
String name = new String("yjt"); //用new构造方法创建name对象再赋值“yjt”
System.out.println(name); //输出“yjt”
}
}
- 两种方法的区别
很显然两种方式的形式是不一样的,但是这两种不一样的创建对象方式有什么不一样的影响吗?
直接赋值:对象存入常量池中;当JVM创建字符串对象前会先去常量池中找有没有一个字符串内容与当前字符串相同,有:将已有的地址赋值给变量;无,创建新的对象
例如
public class StringLearn {
public static void main(String[] args) {
String name1="tom"; //创建对象name1,赋值"tom"
String name2="tom"; //创建对象name2,赋值"tom"
System.out.println(name1==name2); //判断name1是否等于name2
String name3="Tom"; //创建对象name3,赋值"Tom"
System.out.println(name1==name3); //判断name1是否等于name3
}
}
运行结果为
为什么name1会等于name2,却不等于name3呢?
我们首先要知道,在java中判断两个引用类型数据是否相等,实质上是判断它们的地址是不是一样的,而在直接赋值时,当JVM创建字符串对象前会先去常量池中找有没有一个字符串内容与当前字符串相同,有:将已有的地址赋值给变量;无,创建新的对象。在这段代码中,name2被创建前JVM在常量池找到了和其一样的字符串“tom”,并找到其地址,赋给了name2,所以name1与name2地址是一样的,因此他们相等;而name3的“Tom"在常量池找不到,因此被重新创建赋予了新的地址,所以name1不等于name3。
new :直接存入堆内存;每new一次就会创建一个新的对象
public class StringLearn {
public static void main(String[] args) {
String address=new String("河南郑州高新区"); //创建对象address赋值
//"河南郑州高新区"
String address2=new String("河南郑州高新区"); //创建对象address2赋值
//"河南郑州高新区"
System.out.println(address2==address); //结果为false
}
}
和直接赋值不同,两个对象明明对应的字符串都是 "河南郑州高新区",它们却不相等,是因为new构造方法使用时一定会创造一个新的对象,那么就一定会有一个新的地址,所以无论字符串如何,这些对象因为地址不同,一定不相等。