String创建方式的区别
String创建方式主要有两种方式;一种是 String str = "Hello"; 定义;另一种是 String str = new String("Hello"); 定义,接下来我们就来看一下这两种方法的区别;
public class Test {
public static void main(String[] args) {
String name1 = "Tom"; //1
String name2 = "Tom"; //2
String address3 = new String("Tom"); //3
String address1 = new String("Kate"); //4
String address2 = new String("Kate"); //5
System.out.println(name1==name2); //6
System.out.println(address1==address2); //7
System.out.println(name1==address3); //8
System.out.println(address1.equals(address2)); //9
}
}
true
false
false
true
如图,这个图是模拟上述代码中字符串创建的过程;我们都知道Java内存中有堆,还有常量池;通过 String 变量 = "字符串"; 创建的字符串一般会在常量池中;在常量池创建新字符串的原则 :先在常量池寻找有没有与需要创建的字符串相同的字符串,如果有,则直接将变量指向已存在的字符串;如果没有,则在常量池中开辟空间,创建需要的字符串,再将变量指向字符串。
明白常量池创建字符串的原则后,开始解析我们的代码;注释为1的那一行代码执行时会在先在常量池中寻找有没有叫“Tom”的字符串,发现没有,则开辟空间,创建该字符串并将地址赋值给 name1 ;注释为2的那一行代码执行时也会先在常量池中寻找是否有叫“Tom”的字符串,发现已存在为“Tom”的字符串,则会直接将该字符串的地址赋值给 name2;因此, name1 == name2 为true (指向同一地址,地址自然相同);
而通过 new String("字符串"); 创建的字符串是储存在堆中的,它不会像在常量池中寻找已存在的字符串,取而代之的则是直接创建新的对象,也就是每执行一个 new String(); 都会创建一个新的对象;理解了这我们接着看;
注释为3、4、5的三行代码是分别在堆中创建对象“Tom”、“Kate”和“Kate”;并分别将地址赋值给 address3、address1 和address2;因此 address1 == address2 为false,虽然内容一样都为“Kate”,但地址根本不一样;同理 name1 == address3 也为false;不过 address1.equals(address2) 为 true;因为 address1 和address2 虽然地址不同,但内容相同,都是“Tom”,故为true。
== 与 equals 的区别
== 是比较两者的地址是否相同,同为true,否为false;如果比较对象为数值型,则会比较大小是否相同;
equals 是比较两者的内容是否完全相同,即内容相同就为true,否则false。