为什么说String类是特殊类?说它是基本数据类型它又不是,说它是引用数据类型,看了(3)中的叙述,又发现它不似其他引用类型,所以很特殊,要单独记忆。
(1)首先说String类的字符串常量。字符串常量就是String类的匿名对象,也就是说只要代码中出现字符串常量,就会在堆内存中有这个匿名对象,且该字符串常量会入池,也就是程序中再次出现该字符串常量还是之前堆内存中的那个。
看一下下面这段代码:
public class TestDemo
{
public static void main(String args[])
{
String stra="hello";
String strb="hello";
System.out.println(stra==strb);
}
}
“= =”运算符比较的是两个变量栈内存的内容,也就是两者指向堆内存的那个地址。运行结果:true。也就是两个变量栈内存指向同一个堆内存。
(2)字符串常量一经定义就不可再改变。这个很重要,也就是说之后你怎么改一个String类的变量的内容,实际上只是在变更指向的堆内存地址。
例如:
public class TestDemo
{
public static void main(String args[])
{
String stra="hello";
String strb="hello";
System.out.println(stra==strb);
strb+="world";
System.out.println(stra==strb);
}
}
strb本来指向和stra一样,
strb+=“world”; 这句代码,做了以下操作:
首先,堆内存创建了"world"字符串,并入池。
然后,将"world"拼接在"hello"后面,形成新的字符串”helloworld“,在堆内存有创建了”helloworld“,并入池。
最后,将strb栈内存的内容改成”helloworld“的地址,即strb指向”helloworld“这块堆内存。
自始至终,每个字符串的内容都没有改变,改变的仅仅是指向关系。
(3)由(2)再理解一下下面的代码:
public class TestDemo
{
public static void main(String args[])
{
String str="hello";
fun(str);
System.out.println(str);
}
public static void fun(String temp)
{
temp="world";
}
}
//输出:hello
程序中,fun(str); 发生了引用传递,temp和str指向同一个堆内存,对于其他引用类型来说,下面改变temp指向的内容就会改变str,而对于String类,从(2)中就可以知道,String类对象内容的改变是通过改变指向实现的,字符串一经定义是不可改变的,所以str仍指向”hello“,输出它的内容不变。