publicclassTestMain{publicstaticvoidmain(String[]args){Personp1=newPerson(10);modify(p1);//修改p1引用的对象System.out.println(p1);}publicstaticvoidmodify(Personp){//使用此函数修改引用的指向p=newPerson(20);}}classPerson{//实验用类publicintage;@OverridepublicStringtoString(){return"Person[age="+age+"]";}publicPerson(intage){this.age=age;}}输出结果什么是Person[age=10]不应该是Person[age=20]么?
2 回答
拉丁的传说
TA贡献1789条经验 获得超8个赞
是时候展现一下我的JAVA基础知识了,2333。我按照执行顺序给你写注释好了。Personp1=newPerson(10);//创建了一个对象//p1.age=10;modify(p1);//modify函数传参,创建了一个在modify函数里面的局部变量p//你应该明白p是一个新的变量,这里类似于执行了p=p1,这两个是指向的同一个对象的//p.age=10;p=newPerson(20);//注意,这里!这里!//这里是p被重新赋值了,p指向了新的对象newPerson(20);//p.age=20;//和p1指向的那个对象一毛线关系都没有啊所以,你的代码是在函数内部,把局部变量给重新赋值了。是没法修改到外面的对象的,因为你已经把唯一能访问到外面那个p1的p给重新赋值了!publicstaticvoidmodify(Personp){p.age=20;//只有这样才能修改对象!}同理,如果你写成这样:publicstaticvoidmodify(Personp){p=null;//对外面的p1没有任何影响}我举个例子,你就比较好理解了。你创建了一个100000000个元素的数组,比如就叫p1,你把数组通过参数传进函数里面,那么:这个参数p(类似于p=p1),p和p1他们是指向同一个对象。不是说modify(int[]p)重新创建了100000000个元素的数组。这个应该很好理解。那么:然后你通过p的内置函数怎么操作p都行,都是操作的那100000000个元素的数组。但是,你不能把p重新赋值啊。重新赋值它就不是之前那个数组啦!比如:你重新p=newint[100000000],就创建了一个新的100000000个元素的数组啊。你执行p=null,也只是销毁了这个引用,不让它指向100000000个元素的数组而已。对外面p1的那个数组不会再有任何影响了。看到答案里好多人对这个有误解额。。。说不是一个对象的。说不能在函数里改变参数指向的对象的。说int是传值的。说什么的都有,2333。补充:关于JAVA的函数传参数,你应该也听说过,所谓"基本数据类型是传递的值,其它都是传递的引用"。个人理解是这样的。你传递个Person的对象进去,你可以用SetAge()什么的修改这个对象。但是基本的数据类型,比如Integer、String等等,他们没有什么内置函数能改变他们自己。所以,你传递进去一个int的参数,就算其实是传递的引用,你也只能对int做重新赋值,一重新赋值,就表现成传递的是"值"(永远影响不到函数外面)。
千巷猫影
TA贡献1829条经验 获得超7个赞
首先你得知道什么是值传递和引用传递。引用传递本身其实是传递内存地址,即一个数字。而数字这样的基本类型传递是复制传递,即拷贝一个值从实参到形参,两者改变互不影响。publicclassTestMain{publicstaticvoidmain(String[]args){Personp1=newPerson(10);//1.假设这里的Person(10)对象保存的内存地址为:01002modify(p1);//2.将01002地址传入,将复制01002给实参,但是p1还是01002System.out.println(p1);//4.打印出p1(01002)指向的对象,则还是之前的Person(10)}publicstaticvoidmodify(Personp){p=newPerson(20);//3.假设这里的Person(20)的内存地址为01010,然后赋值给了p。但是由于p是上面p1的一个拷贝,p的改变不影响p1,因此函数结束后p1依旧是01002//5.但是这里如果是类似p.setAge()这样的话,由于并没有改变引用值(即地址),所以这里的操作是去改变p1指向的对象}}
添加回答
举报
0/150
提交
取消