有趣的java,jvm

蘑菇蘑菇 发布于 2013/07/29 17:08
阅读 363
收藏 0
public class User {
    String geo;
    public String getGeo() {
		return geo;
	}
	public void setGeo(String geo) {
		this.geo = geo;
	}
	public User(String s){
		geo = s;
	}
	void f(User d){
		d = new User("d1");
		d.setGeo("gg");
	}
	public static void main(String[] args) {
		User dddd = new User("dddd");
		User qq = new User("qq");
		qq.f(dddd);
		System.out.println(dddd.getGeo());
		System.out.println(qq.getGeo());
	}
}

输出是:

dddd

qq

请问高手,为什么是dddd而不是gg,JVM在new对象的时候都做了啥?

加载中
0
子木007
子木007
又是值与地址的问题
duty
duty
回复 @xesam :那还请不吝赐教,有不对的地方还望指正,大家一起学习。最近确实研究了一下jvm调优。
xesam
xesam
回复 @breaking : 不完全准确吧。。
duty
duty
回复 @蘑菇蘑菇 : 既然说到了jvm,就说说jvm内存管理机制的一部分吧,函数内的变量保存在栈里,变量对象保存在堆里。相当于函数内变量只持有一个对象的引用地址。
蘑菇蘑菇
蘑菇蘑菇
怎么说呢
0
无量神通
无量神通

f(User d)函数传进去的参数是一个引用,函数内部有一个这个引用的复制,所以你再f函数里面改变的还是函数内部的d而不是函数外部的d。用C++表示就是:

void f(User *d)
{
   d = new User();
}
这样当然不会修改外部的d了,C++中如果想要修改外部的d,应该这样写:

void f(User **d)
{
    *d = new User();
}
java中不知道该怎么写……

蘑菇蘑菇
蘑菇蘑菇
哦。。。好像有点明白了。。3q
0
奥西里斯
奥西里斯
感觉应该是参数生成一个新的引用指向传进来对象的地址,然后把这个引用指向了一个新的对象,所以对传进来的原对象没有影响。
0
bxkq
bxkq

传值调用与引用调用的问题,当你调用qq.f(dddd);的时候,你传入的是dddd这个对象的引用地址,在f函数里,使用了new改变了传入的引用地址,所以,更该该对象的时候,dddd这个对象原本的地址并没有改变,所以dddd这个对象没有任何变化。仅此而已。第二个输出应该不难理解吧。

也就是说,在JAVA里边,你使用new的时候会改变对象的引用地址,而不是对象本身。基本类型和String是传值调用,其它任何对象间的传递,都是引用调用。记住这个就OK了~~~

蘑菇蘑菇
蘑菇蘑菇
ok!谢谢!
0
静虚
静虚
唉,这不是new的问题。这是参数传递的问题。Java中使用的值传递。是将dddd那个对象的引用copy个一份,传个方法f()。而dddd这个引用还是指向的是原先的那个引用。这样说明白否。
0
静虚
静虚

引用来自“静虚”的答案

唉,这不是new的问题。这是参数传递的问题。Java中使用的值传递。是将dddd那个对象的引用copy个一份,传个方法f()。而dddd这个引用还是指向的是原先的那个引用。这样说明白否。
纠正一下,是还是指向的是原先那个对象。
蘑菇蘑菇
蘑菇蘑菇
3q,比较明白了~
0
ilxlf
ilxlf

方法:void f(User d) 参数d本质上就是一个指针。当你写:qq.f(dddd)的时候,就是把dddd这个对象的指针传递进去了。

void f(User d){
    d.setGeo("gg");
}
上面的代码,才是你要的效果。

0
LianyouCQ
LianyouCQ

在java中只有值传递它们所谓的引用传递是受c的影响的一种说法,其实也是传递的引用的地址值。

public class User {
   。。。。。
   void f(User d){ // 这里传递的是对象d的地址值
		d = new User("d1"); // 将对象d的地址值重新赋值为new User("d1");  
             d.setGeo("gg");  
      }
   public static void main(String[] args) {
		User dddd = new User("dddd"); 
		User qq = new User("qq");
		qq.f(dddd); /* 将dddd的地址值的一份拷贝传到f()方法中,如果f()方法中没有d=new User("d1");那么此时拷贝值与dddd的地址值完全一样,所以就相当于操作dddd,就会显示gg*/
		System.out.println(dddd.getGeo());
		System.out.println(qq.getGeo());
	}
}

LianyouCQ
LianyouCQ
嗯,改变了。
蘑菇蘑菇
蘑菇蘑菇
嗯嗯。。。谢谢,再请问一下,f方法之后,dddd的原先地址值现在存了new出来的对象,所以dddd的内存地址值还是改变了。。是吗?
0
王瑞平
王瑞平
认真虚心学吧,这个很基础
返回顶部
顶部