1.String
1.String类初始化后是不可变的
它的成员方法都默认为final方法。相关的任何change操作都会生成新的对象。
String str1 = "abc";
str1 = "bcd";
String str2 = new String("abc");
String str3="a"+"bc";
System.out.println(str1==str3); //true
这时,str1只是指向了字符串常量池中的“bcd”字符串常量。
new关键字产生的对象存放在堆中,引用存在栈中,即str1和str2存放在栈中,new生成的“abc”存放在堆中,同时指向常量池中的“bcd”。
jvm方法区存在字符串常量池,每当我们创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就直接返回常量池中的实例引用。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。由于String字符串的不可变性我们可以十分肯定常量池中一定不存在两个相同的字符串。
Java中的常量池,实际上分为两种形态:静态常量池和运行时常量池。
2.String 的+号
String s = "a" + "b" + "c";
String s1 = "a";
String s2 = "b";
String s3 = "c";
String s4 = s1 + s2 + s3;
s的创建只生成一个对象,而s4生成两个对象,每加一次生成一个对象;
字面量"+“拼接是在编译期间进行的。而字符串引用的”+"拼接运算实在运行时进行的,新创建的字符串存放在堆中。
2.区分==
和equals
(1)对于==,如果作用于基本数据类型的变量(byte,short,char,int,long,float,double,boolean ),则直接比较其存储的"值"是否相等;如果作用于引用类型的变量(String),则比较的是所指向的对象的地址(即是否指向同一个对象)。
(2)equals方法是基类Object中的方法,因此对于所有的继承于Object的类都会有该方法。在Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。
(3)对于equals方法,注意:equals方法不能作用于基本数据类型的变量。如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;而String类对equals方法进行了重写,用来比较指向的字符串对象所存储的字符串是否相等。其他的一些类诸如Double,Date,Integer等,都对equals方法进行了重写用来比较指向的对象所存储的内容是否相等。
3.String、StringBuffer、StringBuilder的区别
(1)String中的对象是不可变的,也就可以理解为常量,显然线程安全;StringBuffer 中的方法大都采用了synchronized 关键字进行修饰,因此是线程安全的;StringBuilder非线程安全;
4.String和StringBuffer传值
public static void main(String[] args) {
//1.String类型
String str1="hello";
String str2="world";
System.out.println(str1+"----------------"+str2);//hello----------------world
change(str1,str2);
System.out.println(str1+"----------------"+str2);//hello----------------world
//2.StringBuffer类型
StringBuffer sb1=new StringBuffer("hello");
StringBuffer sb2=new StringBuffer("world");
System.out.println(sb1+"-----------------"+sb2);//hello----------------world
change2(sb1,sb2);
System.out.println(sb1+"-----------------"+sb2);//hello----------------worldworld
}
private static void change2(StringBuffer sb1, StringBuffer sb2) {
sb1=sb2;
sb2=sb1.append(sb2);
}
public static void change(String str1, String str2) {
str1=str2;
str2=str1+str2;
}
Java中只有值传递,不过要清楚值是变量实际值还是引用对象的地址。
change()方法中str1和str2改变了指向的对象,但是和main方法无关;
change2()方法中sb2指向的对象本身改变了,而main中sb2也指向那个对象,自然会影响main中的变量。