1.前言:
String是一个引用类型,这个类里面有两个成员变量
value( private final char 类型的数组,用于存放字符串) , hash(int 类型,在字符串常量池中寻找,本文用一个更简单想法,不用hash)。
在jdk1.8里面,字符串实际保存char类型的数组里面。
2.引入字符串常量池的案例代码:
class Example{
char[] arr = {'a','b','c'};
String str = "test";
}
public class Test {
public static void exchage(char [] arrs,String strs){
arrs[0]='d';
strs = "qwe";
}
public static void main(String[] args) {
Example example = new Example();
exchage(example.arr,example.str);
System.out.println("str="+example.str);
System.out.println("arr[0]="+example.arr[0]);
}
}
运行结果图
3.问题
在上述代码中,为什么arr[0]的值改变了而 str的值却没有改变?
解释:
1.example.str 传给strs的是值,而地址并没有传过去,strs是在栈上开辟的,所以出了exchange的方法,这个strs占用的空间就会被回收。所以并不会影响str的值。
2. 改变arrs的值就会改变arr的值:因为两个数组指向的同一个地址。
由地址找值,只要值改变,另外个指向这个地址的数组里面存放的值也会改变。
4.字符串常量池
4.1字符常量池的定义:
字符串常量池就是一个固定大小的HashTable(用于快速查找的数据结构)。
4.2为什么需要字符串常量池
在Java程序中,一些常量经常使用,为了使得程序更快的运行,节省内存,Java为8中基本数据类型和String类提供了常量池。
4.3用代码理解字符串常量池
String str1 = "abcd";
String str2 = "abcd";
String str3 = new String("abcd");
String str1 =new String ("abcd");
第一行代码解释:
假设 “abcd” 这个对象的地址是 0x89, 由于字符串常量池中没有 “abcd” ,“abcd”会被先存入常量池,返回值是这个对象的地址0x89,而这个0x89也会被保存在str1中。
第二行代码解释:
str2存放的是abcd,而此时字符常量池已经存在" abcd ", 所以str2拿到的也是0x89。
第三行代码解释:
str3自己new了一个String,Stirng里面的value存放着“abcd”的地址0x11,而这个new出来的String的地址0x53会被存放在str3。
第四行代码解释:
str4自己new了一个String,Stirng里面的value也存放着“abcd”的地址0x11,而这个new出来的String的地址0x33会被存放在str4。
4.4总结
str1存放着与str2相同的地址,则str1==str2
然而str3!=str4,因为两个存放的地址不一样的,但是它们都存放着“abcd”