我们首先来看题(这种题型基本上每年都会考,一不小心就会翻车,一定要重视):
要是不管引用调用(call by reference)这几个字的话可以算出调用g()方法之后的返回值是19,加上刚开始定义的a,最后的答案是24,但是加上这几个字之后再调用时,a的地址或者说堆栈发生了变化(具体变化大家可以搜一下传递引用之后堆栈变化的文章,在这我们只针对这一类题型讲解就不具体解释了),最后得出来的值就不是24而是28了,接下来我们看解析:
大家只要记住:
1.引用不会改变已声明并定义的变量,即形参不会改变主方法中的实参
2.地址的引用改变后会影响所有关于地址的引用
这两句话遇到这种题基本上就不会有什么问题了,也就是说只要看到引用调用(call by reference)的话,就拿被调用的方法里面入参的最终值进行计算就行了,只要细心一点一般情况下不会出错,但有的题目不是引用调用是值调用(该怎么算怎么算),这个要认真审题。
接下来我们来看下java代码对这两种调用的实际应用:
java中基本数据类型调用接口发生的是值传递,类是引用传递(不知道这样理解对不对)
public class SureTest {
public static void main(String[] args) {
int i=0;
System.out.println("值传递之前i的值是:"+i);
callByValue(i);
System.out.println("值传递之后i的值是:"+i);
Person person=new Person();
person.setName("马化腾");
System.out.println("引用传递之前的名字是:"+person.getName());
CallByReference(person);
System.out.println("引用传递之后的名字是:"+person.getName());
CallByReferenceTwo(person);
System.out.println("调用后开辟新堆栈之后的名字是:"+person.getName());
}
/**
*值调用
* @param i 入参
*/
public static void callByValue(int i){
i=10;
}
/**
* 引用调用
* @param person 实体类
*/
public static void CallByReference(Person person){
person.setName("麻花藤");
}
/**
* 引用调用(开辟一个新的堆栈)
* @param person 实体类
*/
public static void CallByReferenceTwo(Person person){
person=new Person();
person.setName("腾化麻");
}
}