为了账号安全,请及时绑定邮箱和手机立即绑定

java中引用传递问题,在函数中修改引用的指向,会不会影响实参?

java中引用传递问题,在函数中修改引用的指向,会不会影响实参?

富国沪深 2019-02-20 17:18:10
public class TestMain { public static void main(String[] args) { Person p1 = new Person(10); modify(p1); //修改p1引用的对象 System.out.println(p1); } public static void modify(Person p){ //使用此函数修改引用的指向 p = new Person(20); } } class Person { //实验用类 public int age; @Override public String toString() { return "Person [age=" + age + "]"; } public Person(int age) { this.age = age; } } 输出结果什么是 Person [age=10]不应该是Person [age = 20] 么?
查看完整描述

6 回答

?
杨魅力

TA贡献1811条经验 获得超6个赞

是时候展现一下我的JAVA基础知识了,2333。
我按照执行顺序给你写注释好了。

Person p1 = new Person(10);
//创建了一个对象
//p1.age=10;

modify(p1); 
//modify函数传参,创建了一个在modify函数里面的局部变量p
//你应该明白p是一个新的变量,这里类似于执行了p=p1,这两个是指向的同一个对象的
//p.age=10;

p = new Person(20);
//注意,这里!这里!
//这里是p被重新赋值了,p指向了新的对象new Person(20);
//p.age=20;
//和p1指向的那个对象一毛线关系都没有啊

所以,你的代码是在函数内部,把局部变量给重新赋值了
是没法修改到外面的对象的,因为你已经把唯一能访问到外面那个p1的p给重新赋值了!

public static void modify(Person p){
   p.age=20; //只有这样才能修改对象!
}

同理,如果你写成这样:

public static void modify(Person p){
   p = null;//对外面的p1没有任何影响
}

我举个例子,你就比较好理解了。
你创建了一个100000000个元素的数组,比如就叫p1,你把数组通过参数传进函数里面,那么:
这个参数p(类似于p = p1),p和p1他们是指向同一个对象
不是说modify(int[] p)重新创建了100000000个元素的数组。
这个应该很好理解。

那么:
然后你通过p的内置函数怎么操作p都行,都是操作的那100000000个元素的数组。
但是,你不能把p重新赋值啊。
重新赋值它就不是之前那个数组啦!

比如:
你重新p = new int[100000000],就创建了一个新的100000000个元素的数组啊。
你执行p = null,也只是销毁了这个引用,不让它指向100000000个元素的数组而已。
对外面p1的那个数组不会再有任何影响了。

看到答案里好多人对这个有误解额。。。
说不是一个对象的。
说不能在函数里改变参数指向的对象的。
说int是传值的。
说什么的都有,2333。

补充:
关于JAVA的函数传参数,你应该也听说过,所谓"基本数据类型是传递的值,其它都是传递的引用"。
个人理解是这样的。
你传递个Person的对象进去,你可以用SetAge()什么的修改这个对象。
但是基本的数据类型,比如Integer、String等等,他们没有什么内置函数能改变他们自己
所以,你传递进去一个int的参数,就算其实是传递的引用,你也只能对int做重新赋值,一重新赋值,就表现成传递的是"值"(永远影响不到函数外面)。

查看完整回答
反对 回复 2019-03-01
?
慕容3067478

TA贡献1773条经验 获得超3个赞

首先你得知道什么是值传递和引用传递。引用传递本身其实是传递内存地址,即一个数字。而数字这样的基本类型传递是复制传递,即拷贝一个值从实参到形参,两者改变互不影响。

public class TestMain {
    public static void main(String[] args) {
        Person p1 = new Person(10); // 1. 假设这里的Person(10)对象保存的内存地址为:01002
        modify(p1);  // 2. 将01002地址传入,将复制01002给实参,但是p1还是01002
        System.out.println(p1); // 4. 打印出p1(01002)指向的对象,则还是之前的Person(10)
    }

    
    public static void modify(Person p){ 
        p = new Person(20); // 3. 假设这里的Person(20)的内存地址为01010,然后赋值给了p。但是由于p是上面p1的一个拷贝,p的改变不影响p1,因此函数结束后p1依旧是01002
        
        // 5. 但是这里如果是类似p.setAge()这样的话,由于并没有改变引用值(即地址),所以这里的操作是去改变p1指向的对象
    }
    

}
查看完整回答
反对 回复 2019-03-01
?
慕雪6442864

TA贡献1812条经验 获得超5个赞

其实p = new Person(20)是重新开辟了一个内存地址,跟原来的那个p1没有任何的关系了。如果是

public static void modify(Person p){ 
        p.age=20;
    }
    

这样结果就是20了。

查看完整回答
反对 回复 2019-03-01
?
白板的微信

TA贡献1883条经验 获得超3个赞

public static void main(String[] args) {

    Person p1 = new Person(10);      //此处调用的是构造方法 直接执行出age=10的结果
    modify(p1);  
    System.out.println(p1);
}


你要想出age=20的结果 应该这样


public class testFromWeb01 {
public static void modify(Person p){ //使用此函数修改引用的指向
    p = new Person(20);
    System.out.println(p);        //修改在这里!!!!!
}

public static void main(String[] args) {
    Person p1 = new Person(10);
    modify(p1);  //修改p1引用的对象
}

}

查看完整回答
反对 回复 2019-03-01
  • 6 回答
  • 0 关注
  • 483 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信