话不多说了,直接上代码。
public class Demo {
//static String str = "hello world!";
//static String str = new String("hello world!");
//static char[] ch = new char[]{'A','B','C'};
public static void test(String str,char[] ch,int a) {
System.out.println("str=" + str);
System.out.println("str.hashCode():" + str.hashCode());
str = "-------";
System.out.println("str=" + str);
System.out.println("str.hashCode():" + str.hashCode());
ch[0] = 'G';
a = 11;
}
public static void main(String[] args) {
String str = "hello world!";
String str1 = new String("hello world!");
char[] ch = new char[]{'A','B','C'};
int a = 1;
System.out.println("str.hashCode():" + str.hashCode());
System.out.println("str1.hashCode():" + str1.hashCode());
test(str,ch,a);
System.out.println("a=" + a);
System.out.println("str=" + str);
System.out.println("str.hashCode():" + str.hashCode());
str = "ooooooo";//改变str的值
System.out.println("str.hashCode():" + str.hashCode());
System.out.println("str1.hashCode():" + str1.hashCode());
for (char e : ch) {
System.out.print(e);
}
/* ①上述str和a变量打印出来的值并没有改变,但str打印出来的内存地址(hashCode)却有变化的;
* ②str打印出来的内存地址(hashCode)相同。
*
* 推测:
* 不同String变量的值只要相同,指向就相同。String对象在常量池中创建(开辟空间)的,调用者访问的是常量池中空间
* 如果上面推测成立,那么疑惑就来了。(建议把前面的记住就行了)
* String类型变量在方法间传参时,是传递引用(内存地址)还是值传递?。
*
* 这里先说明C++的String变量引用传递是传递内存地址的,也就是说访问的是变量的实际内存空间,
* 修改变量的值就是修改该内存空间中的值。
* 在Java中对象是引用传递的,但如果字符串作为常量使用,显然单纯的引用传递是不合适的。
* 这里有两个考虑:1.常量是不能改变值的,2.如果能改变,这就属于共享数据,涉及数据安全问题了。
* 所以做法是修改值时,会在常量池先开辟好一个String对象空间,再把引用(内存地址)赋值给String变量,使其指向该空间。
* 如果是值传递,当一个字符串有1G大的时候,想想这个字符串传来传去是什么情况?搬着块大石头走来走去舒服吗?嘿嘿,这是笑话
* 相同的数据,1G大的空间,不会再开辟一个的。
*/
}
}
控制台打印结果:
str.hashCode():-217287203
str1.hashCode():-217287203
str=hello world!
str.hashCode():-217287203
str=-------
str.hashCode():-1680751795
a=1
str=hello world!
str.hashCode():-217287203
str.hashCode():-1282542897
str1.hashCode():-217287203
GBC