String:字符串类型。
有多种构造方式,常用的有以下三种:
//第一种用的最多
String str1 = "helloworld";
//第二种
String str2 = new String("helloworld");
//第三种
char[] array = {'h','e','l','l','o'};
String str3 = new String(array);
“helloword”是存储在堆中的常量池当中的。并且在常量池中只有一份。
String源代码中是被final所修饰的,被final修饰的都不能被继承
被final所修饰的方法:密封方法
被final所修饰的类:密封类
String使用双等号进行比较时,并不是比较内容,比较的是两个引用是否指向同一个对象。
然后选择题中会问到str1是否等于str2
String str1 = "hello";
String str2 = new String("hello");
System.out.println(str1 == str2); //false
System.out.println(str1.equals(str2)); //true
因为str1 == str2 比较的是两个的引用的地址是否相同,如下图,
而str1.equals(str2)比较的是两个里面的内容是否相同。
再看下面两个:理解常量池中的存储的对象只有一份
String str3 = "he"+"llo"; //两个常量在比较前就会合成hello
System.out.println(str1 == str3); //hello在常量池中只有一份
//true
String str4 = "he"; //he在常量池
String str5 = str4+"llo"; //llo也是常量,在常量池,str4是变量,在运行时才会
System.out.println(str4 == str5); //str5引用的是he 和llo拼接起来的在堆当中的value
//false
最后一个:
String str6 = new String("he")+"llo";
System.out.println(str1 == str6);
str6引用的是:new了一个value在堆上,指向he;value的地址和llo的地址的组合就是str6所指向的。
String的intern方法手动把String对象加入到常量池中。
String str1 = "hello";
String str2 = new String("hello").intern();
System.out.println(str1 == str2);
上面已经说了不加intern是false,加了之后就会把hello的地址给str2。
String字符串不可改变:
为什么不可变?看下面代码注释
String str = "hello" ;
str = str + " world" ; //在常量池中创建了一个world
str += "!!!" ; //又在常量池中创建了一个 hello world
System.out.println(str);
//打印出hello world ,但world本身没有变
还有就是substring修改:也是不能改变原来的Hello字符串
String str = "Hello";
str = "h" + str.substring(1); //创建新的字符串
System.out.println(str);