面试之new创建对象和用字符串常量创建对象的区别

public class StringDemo2 {
    public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = "hello";
        System.out.println(s1 == s2);// false
        System.out.println(s1.equals(s2));// true
    }
}

面试之new创建对象和用字符串常量创建对象的区别
(1)、首先,通过main()方法进栈。
(2)、然后再栈中定义一个对象s1,s1由new创建,因此去堆中开辟一个内存空间,将内存空间的引用赋值给s1,“hello”是常量,然后去字符串常量池查看是否有hello字符串对象,没有的话分配一个空间存放hello,并且将其空间地址存入堆中new出来的空间中。
(3)、在栈中定义一个对象s2,s2不是由new创建,因此去字符串常量池中查看是否有”hello”字符串对象,有则直接把“hello”的地址赋值给s2。
(4)、即s1中存的是堆中分配的空间,堆中分配的空间中存的是字符串常量池中分配空间存放”hello”的空间的地址值。而s2中之中存的是字符串常量池中分配空间存放”hello”的空间的地址值。
(5)、由于s1与s2中存放的地址不同,所以输出false。因为,类String重写了equals()方法,它比较的是引用类型的 的值是否相等,所以输出true。即结果为false、true。

String a1 = new String("nihao");

可以化为

String para = "nihao"; 
String a1 = new String(para);
就会发现String a1 = new String("nihao"); 这一句代码实际上创建了2个对象, 一个是String对象,存放在堆中, 一个是字符串常量对象,存放在串池中