面试宝典(二):参数传递问题

 

方法调用过程中,参数传递有两类:值传递、引用传递。

值传递,方法调用时,实际参数会把值传递给方法中对应的形式参数。在方法执行过程中,形式参数值的改变不会影响实际参数的值。

引用传递,也称地址传递。方法调用时,实际参数的引用(地址,而不是其真实值)传递给方法中对应形式参数。在方法执行过程中,针对形式参数的操作,实际上就是针对实际参数的操作,形式参数值的改变将会影响实际参数的值。

而在Java中,只有值传递。基本类型传递的是其值的副本,引用类型传递的是其引用的副本。

因此,将会衍生出来几种面试题,颇具迷惑性。

 

简单版:

public void print() {
  int i = 0;
    plus(i);
    System.out.println(i);
}
public void plus(int i) {
  i = i + 1;
}

此题答案为0,而并非是1。其原因就是plus方法接到的只是实际参数 i 的值的拷贝,即0。而plus方法内的 形式参数 i,plus方法无论对其做什么改变,都不影响原实际参数的值。

 

进阶版:

public void print() {
    int i = 0;
    plus(i);
    System.out.println(i);
}
public int plus(int i) {
    return i++;
}
​
public void print() {
    int i = 0;
    i = plus(i);
    System.out.println(i);
}
public int plus(int i) {
    return ++i;
}


此2题答案依然为0。传参部分解释同上。而迷惑你的,无非是plus方法多了返回值,还有,出现了 i++。一直以来,i++ 和 ++i 都是最易混淆的知识点,加上了这个知识点,更具迷惑性。为啥还是0呢?很简单,除了传参部分的原因,plus返回的值没有被接收/赋值,也是很重要的原因。 

但是,plus方法返回的值被接收/赋值,结果就会是 1 吗?

public void print() {
    int i = 0;
    i = plus(i);
    System.out.println(i);
}
​
public int plus(int i) {
    return i++;
}

答案依然为0。为啥呢?简单的解释, i++ 先用后加!再来个变种:

public void print() {
    int i = 0;
    i = plus(i);
    System.out.println(i);
}
​
public int plus(int i) {
    return ++i;
}

这次答案终于为1了。为啥呢?简单的解释,++i 先加后用!

中级进阶版:

public void print() {
int a = 3;
int b = 4;
​
    System.out.println("交换前:");
    System.out.println("a:" + a + ",b:" + b);
​
    swap(a,b);
​
    System.out.println("交换后:");
    System.out.println("a:" + a + ",b:" + b);
}
​
public void swap(int m, int n) {
int temp = m;
    m = n;
    n = temp;
}

 

答案是交换前后,并没有变化。原因依然是值传递,形式参数 m 和 ,得到的依然是实际参数 a 和 b 的值副本,swap方法执行完毕后,m 和 作用域失效实际参数 a 和 b 并无任何影响。

高级进阶版:

public void print() {
    int ages[] = {1, 2, 3};
    System.out.println("交换前:");
    System.out.println("第一个元素:" + ages[0] + ",最后一个元素:" + ages[ages.length - 1]);
    swap(ages);
    System.out.println("交换后:");
    System.out.println("第一个元素:" + ages[0] + ",最后一个元素:" + ages[ages.length - 1]);
}
​
public void swap(int[] ages) {
    int temp = ages[0];
    ages[0] = ages[ages.length - 1];
    ages[ages.length - 1] = temp;
}

答案是互换成功。什么原因呢?值传递依然是传递的 ages 数组对象的引用的拷贝,均指向 ages 数组对象。所以,针对 ages 数组对象的引用的拷贝做操作,相当于直接对 ages 数组对象操作,均会改变其内容。

究极进阶版:

public void print() {
    Person a = new Person(0);
    Person b = new Person(100);
    System.out.println("交换前:");
    System.out.println("a的年龄:"+a.getAge()+"-----------b的年龄:"+b.getAge());
    swap(a,b);
    System.out.println("交换后:");
    System.out.println("a的年龄:"+a.getAge()+"-----------b的年龄:"+b.getAge());
}
​
public void swap(Person x, Person y) {
    Person temp = x;
    x = y;
    y = temp;
}

答案是互换不成功,依然是原来的值。

 

笔者开通了个人微信公众号【银河架构师】,分享工作、生活过程中的心得体会,填坑指南,技术感悟等内容,会比博客提前更新,欢迎订阅。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值