//.java文件会被编译成.class文件,然后在执行.class文件
//在编译期 s1就相当于是String s1="abc";
//字符串都放在字符串常量池中
String s1="a"+"b"+"c";
String s2="abc";
//如果字符串常量池中没有"abc",那么这条语句就会创建出两个对象
//一个字符串放在字符串常量池中,一个字符串对象放在堆中
//如果字符串常量池中有"abc",那么这条语句就只会在堆中创建一个字符串对象
String s3=new String("abc");
//==比较的是内存地址
System.out.println(s1==s2);//true
//String重写了equals方法,比较的是内容是否一样
System.out.println(s1.equals(s2));//true
//s1是在字符串常量池中的,s3是在堆中的
System.out.println(s1==s3);//false
System.out.println(s1.equals(s3));//true
/*
常量与常量拼接就放在字符串常量池中
只要拼接的内容中有一个是变量,都会在堆中创建
*/
String s1="javaEE";
String s2="hadoop";
String s3="javaEEhadoop";
String s4="javaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="javaEE"+s2;
String s7=s1+s2;
System.out.println(s3==s4);//true
System.out.println(s3==s5);//false
System.out.println(s5==s6);//false
System.out.println(s3==s7);//false
System.out.println(s5==s7);//false
String s1="a";
String s2="b";
String s3="ab";
/**
* 如下的s1+s2的执行细节
* StringBuilder s=new StringBuilder();
* s.append("a");
* s.append("b");
* s.toString() --> 约等于new String("ab")
* 如果拼接的都是字符串,那么就是编译期优化
*/
String s4=s1+s2;
System.out.println(s3==s4);//false
String intern = new String("ab").intern();
/**
* intern方法:
* 如果字符串常量池中没有这个字符串,那么就在字符串常量池中创建这样一个字符串,
* 然后返回该字符串的地址;
* 如果有这个字符串,则指向这个字符串
*
* String intern = new String("ab").intern();
* 相当于如果字符串常量池中存在"ab";那本intern指向的就是字符串常量池中的"ab";
* 如果 字符串常量池中不存在"ab";那么intern指向的就是堆中的new String("ab")对象;
*/
/**
* new String("ab")会创建几个对象
* 会创建两个对象:一个是在字符串常量池中,一个在堆中
*
* new String("a")+new String("b")创建几个对象
* 对象1:new StringBuilder;
* 对象2:new String("a");
* 对象3:常量池中的"a";
* 对象4:new String("b");
* 对象5:常量池中的"b";
*
* StringBuilder.toString()会创建一个对象 new String("ab");
* 而且,toString()的调用,在字符串常量池中,没有生成"ab";
* 对象6:new String("ab");
*/