黑马程序员技术交流社区
标题: 有趣的java,jvm [打印本页]
作者: abian 时间: 2013-8-2 23:04
标题: 有趣的java,jvm
- 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对象的时候都做了啥?
作者: xuaner0719 时间: 2013-8-3 00:46
qq.f(dddd);//是传的是User dddd = new User("dddd"), new出来的地址值
你传给了f(User d)方法,d = new User("d1");又new出来一个地址值,会与之前的断开。
故System.out.println(dddd.getGeo())与d.setGeo("gg");没有任何联系- public class Demo {
- public static void main(String[] args) {
- int x = 3;
- A a = new A();
- a.show(x);
- System.out.println(x);
- }
- }
- class A {
- void show(int x) {
- x = 5;
- }
- }
复制代码 就如同上面代码一样它输出的是3,这是个是值传递一样,你上面的是引用传参。
一样的道理,一个是值,一个是地址。
作者: abian 时间: 2013-8-3 09:02
是的,这是障眼法,具有迷惑性
作者: 单凯 时间: 2013-8-3 10:19
这是内存位置的问题,对象在堆里面,方法在方法区内,局部变量在栈里面,他们之前通过指针具有了联系,
你调用函数的时候,其实是把栈里的指针复制到了方法区内,得到的是一个指针副本,并不是对象本身,
而且你这里操作的也只是是指针副本,并没有对以前的对象进行实际的修改,所以值没有变化.
作者: 王清华0 时间: 2013-8-5 10:44
我的看法和二楼一样,简单来说,你使用引用传参的过程中,将引用的内存地址给换掉了,所以无法像正常的引用传参一样,改变原地址的值。
下面我们按照程序运行过程跑一下。
第十七行: User dddd = new User("dddd"); 你创建了一个引用:dddd 它指向的内存地址是一个User实例。我们 可以直接称呼他为"dddd"
第十九行:qq.f(dddd); 你将"dddd"的引用传给了方法void f(User d)中的参数d,该User对象"dddd"就有了两个引用--dddd和d。
第十三行:d = new User("d1"); 这里是又创建了一个叫做"d1"的实例,并且把该实例的引用赋予了d。这样,d就不再指向原来的"dddd"了。
第十四行:d.setGeo("gg"); 此时d指向的是"d1"实例,修改的是"d1"的属性值。而原来的dddd指向的"dddd"不受影响。
这样就说明了,就是因为第十三行的关系,才将原来的引用传参改变了。程序变一下 ,就恢复正常了:- 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.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());
- }
- }
复制代码 其实只是去掉了第十三行而已。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |