作者:欧毅儒 | 来源:互联网 | 2023-05-18 19:56
大家探讨一下这个啊,为什么add3(i);改变不了i的值?publicclasstest{publicstaticintadd3(Integeri){intvali.i
大家探讨一下这个啊,为什么add3(i);改变不了i的值?
public class test {
public static int add3(Integer i){
int val = i.intValue();
val+=3;
i = new Integer(val);
return i;
}
public static void main(String[] args){
Integer i = new Integer(0);
add3(i);
System.out.println(i.intValue());//结果还是0
}
}
30 个解决方案
public static void main(String[] args){
//i是一个对象你没执行方法直接输出i.intValue()
Integer i = new Integer(0);
i= add3(i);
System.out.println(i.intValue());//结果还是0
}
按LZ的意思
static Integer i = new Integer(0);
public static void main(String[] args){
i= add3(i);
System.out.println(i.intValue());//结果还是0
}
public class test {
public static int add3(Integer i){
Integer j = i;//多声明一个变量,调用该方法同时引用传进来的对象.
int val = i.intValue();
val+=3;
i = new Integer(val);//这里i引用了一个新创建的对象,后边操作的就不再外边传进来的对象.所以返回的就是一新对象.并没有改变传进来的那个对象(j)
return i;
}
public static void main(String[] args){
Integer i = new Integer(0);
add3(i);
System.out.println(i.intValue());//结果还是0
}
}
理解add3(Integer i)函数:
我的名字叫add3,如果你想要调用我,请你给我一个Integer对象放到我的i里去,我将取出这个Integer的int值,并+3后重新创建一个新的Intger,它将由i引用(此时我的i将不再引用你的传进来的对象),我会将i返回.
由此可见,并没有修改传进来的Integer对象.
对比:
public static void addString(StringBuffer bf)
{
bf.append("调用我的话将会增加字符串");
}
理解:addString(StringBuffer bf)函数:
我的名字叫addString,如果你想调用我,请给我传一个StringBuffer对象,放到我的bf变量(引用)里,我将会给这个bf对象增加字符串:"调用我的话将会增加字符串".
上边的这个函数,每调用一次就会增加一次,如果我们多次调用它,并且传同个对象进去,那么就会有很多的:"调用我的话将会增加字符串"
public staic void main(String[]args)
{
StringBuffer bf = new StringBuffer("");//创建好StringBuffer对象
addString(bf);//将创建好的对象,传进去
System.out.println(bf.toString());
addString(bf);//再调用一次,传的同一个对象,会在上次调用的基础再增加字符串
System.out.println(bf.toString());
}
答案是0啊!你一直都没改变过main函数中i的值啊!
在add3()里你只是改变了i的引用,让其指向了另一个对象new Integer(3),i原来引用的对象的内容没有改变
add3()方法中参数的传递过程(个人观点,仅供参考):
(1)对于add3(i)的执行实际上是将 Integer(0) 这个对象的句柄传进add(3)方法,也就是说这是参数传递方法中的句柄传递方式。
(2)这是进入add3()方法调用,首先完成的工作是在栈区分配新的空间给Integer i(这里的i是形参,是局部变量),并将传进来的句柄赋给i,完成i的初始化,这时i指向的是外部的对象Integer(0);然后开始进入方法体执行实际的操作,其中i = new Integer(val); 这步操作又将一个新的对象Integer(val)的句柄赋给了i,这时i不仅与main方法里的i存储空间不一样,而且它们指向的对象也不一样,是两个完全没有关系的变量了……
3楼说得很详细了。
add3(Integer i)完成加3动作,但他传递出来的是它方法内的局部变量,而不是类中的实例变量Integer i = new Integer(0);
如果将实例变量Integer i = new Integer(0);为便于理解,将i改为Integer a = new Integer(0),
则add3(Integer i)的传值过程如下:
1.add3(Integer i)中Integer i = a; //i 指向a所指向的Integer(0)对象,设为x。i为一个引用,相当于个指针
2.int val = i.intValue(); // val = 0
3.val+=3; // val = 3
4.i = new Integer(val); //i重新指向new Integer(val) 对象,设为y
5.return i; //返回y对象,而不是最先传进来的x对象
形参跟实参的问题,对于非基本类型,形参相当于实参的副本,你只改变了形参的内容,但是实参并没有改变
public class test {
public static int add3(Integer i){
int val = i.intValue();
val+=3;
i = new Integer(val);
return i;
}
public static void main(String[] args){
Integer i = new Integer(0);
int k = add3(i);
System.out.println(i.intValue());//结果还是0
System.out.println(K);//结果为3
}
}
楼主思维有点混乱啊,haha
public class test {
public static int add3(Integer i){
int val = i.intValue();
val+=3;
i = new Integer(val);
return i;
}
public static void main(String[] args){
Integer i = new Integer(0);
add3(i); //返回给谁????
System.out.println(i.intValue());//结果还是0
}
}
方法调用的5大步骤:1、开辟一个方法栈;2、参数传递;3、方法计算;4、返回值;5、消除这个方法栈
在该过程中,出现的所有临时变量都将随栈消除而等待回收;只有返回只有用!!你那个main()中的add3(i)返回给谁啊??这样就是一句没有用的语句。
看哈25楼。
楼主:
查看Integer类的源码,可以发现
//Integer的属性
private final int value;
//Integer的构造器
public Integer(int value) {
this.value = value;
}
value不可修改
传递的虽然是引用,但是,其中的value是不可修改类型
说错了,我觉得是包装类,如:Integer,Double都是按值传递的
Integer i = new Integer(0);
写成这样是对象啊,传参数的时候 传递的是 对象引用的副本,i 指向的对象并没有受到任何改变。
add3(i)这句是迷惑你的吧。程序里面 又没有接受他的返回值啊。
个人认为 add3(Integer i) 方法里的参数 因为也是i (同名) 可能影响了楼主的判断,如果改成其他的 比如 x y 可能更清楚一点。
另外建议 再看看 java基本类型的装箱 和拆箱。这到题目主要就是考这个的吧。
java的参数传递都是值传递的,当一个变量作为参数传递给方法时,
java会拷贝变量的一个副本作为参数传递给方法
方法内部对该副本的一切修改不影响该变量
你在此传入了一个引用类型的Integer变量,所以java拷贝了该引用
传递给方法,此时该副本也和变量一样指向Integer(0)这个对象,
而方法内部对该参数做了更改,使他指向了一个新的对象Integer(3)
但此更改只是更改了原变量的副本,没有改变原变量,原变量依然指向Integer(0)