package Virtual; class Stan{ String mm = "hello"; } class Virtual { public static void main(String[] args) { Stan s=new Stan(); System.out.println(s.mm); change(s); System.out.println(s.mm); } public static void change(Stan s) { s.mm="say";//其实是改变了mm指向字符串的地址,从指向hello的地址改成指向say的地址,hello还是存在,只是没有指向它 } }
mm刚开始指向的是hello那一片内存,当传入change函数里,对象是原对象的引用,可以直接指向原对象mm的地址,此时如果将s.mm改成say,由于String类型是不可改变的,只能为say重新分配一片内存空间,并且将mm的值指向say的内存,所以输出会改变,
其实是改变了String对象 mm指向字符串的地址,从指向hello的地址改成指向say的地址,hello还是存在,只是没有指向它
再看下一个例子
package Virtual; class Stan{ String mm = "hello"; } class Virtual { public static void main(String[] args) { String s="123"; System.out.println(s); change(s); System.out.println(s); } public static void change(String s) { s="say"; } }
此时s并没有被更改,这是为什么呢?因为传入函数时,是复制了一个String对象副本,这个String对象指向了say的内存空间,但是原String对象指向的还是123的内存空间,所以s并没有发生更改。String类型可以被认为是传值,即另外创建一个String对象,与原对象无关
package Virtual; class Stan{ int temp=10; } class Virtual { public static void main(String[] args) { Stan s=new Stan(); System.out.println(s.temp); change(s); System.out.println(s); } public static void change(Stan s) { s.temp=30; } }
这个跟例子1是一样的,也是传递对象的引用,即地址,并且temp是int型,可以被更改,所以直接改变temp所在的堆区的值为30
未完待续
时间: 2024-10-09 23:37:00