String s1 = "abc";//"abc"是一个对象,将对象赋予类变量s1 String s2 = new String("abc");//这里是两个对象,在内存中存在两个,包括对象abc 和 new 出来的对象 String s3 = "abc"; //由于String类型数据是不可变的,因此‘abc’被放在了常量池中,这里的‘abc’ַ和s1的‘abc’是 //同一个常量abc对象,所以两者的内存地址是同样的。 System.out.println(s1==s2);//false System.out.println(s1==s3);//true 这是这号i
public class StringDemo { public static void main(String[] args) { String str = "Hello"; str = str + "World"; str += "!!!"; System.out.println(str); } }
public static void main(String[] args) { String stra = "hello" ; String strb = "hello" ; String strc = "hello" ; System.out.println(stra == strb);//true System.out.println(stra == strc);//true System.out.println(strb == strc);//true } }
String s = "aa"; s =s + "bb"; String s2 = "aabb"; s == s2;???
这个的结果是false,这时候s 和s2已经不是同样的了,首先看 s2,s2指向的是常量池中的对象,这是肯定的。因此尽管s的值和s2是同样的,可是s指向的不是常量池的中的对象,而是一个新的new出来的对象。 解释以前,先了解一下 + 这个符号,在字符串拼接里面,至关于+ 源码大意为: (new StringBuffer()).append(s3).append(“bbb”).toString; 因此,这里的s指向的是一个新的对象。缓存
总结: 在String的两种声明方式,直接赋予字符值的是,String对象引用获取常量池中对象的地址,因此String声明出来是不能够改变的。new String()出来的是在堆内存建立对象。若是要给每一个对象中的String属性赋予一个初始值,采用String s = ‘abc’方式,这样建立的是常量池中的一个对象,其余对象是获取这个常量的地址。要是new 则每次都要建立,加大内存消耗。还要注意,字符串拼接不要用+ ,会建立对象。安全
public class Demo1 { @Test public void test1() { String s1 = "abc";//"abc"是一个对象,将对象赋予类变量s1 String s2 = new String("abc");//这里是两个对象,在内存中存在两个,包括对象abc 和 new 出来的对象 String s3 = "abc"; //由于String类型数据是不可变的,因此‘abc’被放在了常量池中,这里的‘abc’ַ和s1的‘abc’是 //同一个常量abc对象,所以两者的内存地址是同样的。 System.out.println(s1==s2);//false System.out.println(s1==s3);//true 这是这号i //+ 源码大意为: (new StringBuffer()).append(s3).append("bbb").toString; //是新new出一个新的StringBuffer对象, s3 = s3+"bbb";//这时候s3已经不指向"abc",源对象依旧存在,s3是新的string类型的对象 String s4 = "abcbbb"; String s5 = new String("abcbbb"); System.out.println(s3); System.out.println(s3==s4);//false s3是一个新的String对象 System.out.println(s4=="abcbbb");//true 这个“abcbbb”属于同一个常量池中的对象 System.out.println(s4==s5);//false 一个在常量池,一个是new的对象 } }
String s1 = "abc"; String s2 = new String("abc"); String s3 = new String("abc").intern();//s3实际上是字符串常量"abc" /* s1是常量池中的对象,s2是堆中对象,是不一样对象 */ System.out.println(s1 == s2);//false //二者都是表示字符串常量abc,因此是true System.out.println(s1 == s3);//true //s3是常量池中的对象abc,s2是堆中对象,是不一样对象 System.out.println(s2 == s3); //都表示一个值abc System.out.println(s1 == "abc"); //true System.out.println(s3 == "abc"); //true