话不多说了,直接上代码。
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
时间: 2024-10-01 05:54:36