Java按引用传递?按值传递!

当一个对象被看成参数传递到一个方法后,在此方法内能够改变对象的属性,那么这里究竟是“按值传递”仍是“按引用传递”?java

答:是按值传递。Java语言参数传递只有按值传递。当一个实例对象做为参数被传递到方法中时,参数的值就是该对象的引用的一个副本。指向同一个对象,对象的内容能够在被调用的方法内改变,但对象的引用(不是引用的副本)永远不会改变。数组

Java的参数传递,无论是基本数据类型仍是引用类型的参数,都是按值传递,没有按引用传递!code

Microsoft文档中对引用传递的定义:在方法的参数列表中使用ref关键字,它指示参数按引用传递,而非按值传递。按引用传递的效果是,对所调用的方法中的参数进行任何的修改都反映在此方法中。例如,若是调用方传递本地变量表达式或数组元素访问表达式,所调用方法会替换ref参数引用的对象,而后,当该方法返回时,调用方的本地变量或数组元素将开始引用新对象。对象

不要混淆经过引用传递与引用类型的概念。这两种概念是不一样的。不管方法参数是值类型仍是引用类型,都可由ref修改。当经过引用传递时,不会对值类型装箱。blog

1.基本数据类型参数

public class TransferTest {
    public static void main(String[] args) {
        int num = 1;
        System.out.println("changeNum()方法调用以前:num = " + num);
        changeNum(num);
        System.out.println("changeNum()方法调用以后:num = " + num);
    }

    public static void changeNum(int x) {
        x = 2;
    }
}

运行结果:changeNum()方法调用以前:num = 1,changeNum()方法调用以前:num = 1内存

内存示意

num做为参数传递给changeNum()方法时,是将内存空间中num所指向的那个存储单元中存放的值1传递给了changeNum()方法中的x变量,而这个x变量也在内存空间中分配了一个存储单元,这个时候,就把num的值1传递给了x这个存储单元中。此后在changeNum()方法中对x的一切操做都是针对x所指向到的这个存储单元,与num所指向的那个存储单元无关。文档

因此,在changeNum()方法调用以后,num所指向的存储单元的值仍是没有发生变化,这就是所谓的**“按值传递”**!按值传递的精髓是:传递的是存储单元中的内容,而不是存储单元的引用!it

2.引用数据类型参数

public class TransferTest2 {
    public static void main(String[] args) {
        Person p1 = new Person();
        System.out.println(p1);
        change(p1);
        System.out.println(p1);
    }

    public static void change(Person p2) {
        p2 = new Person();
    }
}

/**
 * Person类
 */
class Person {

}

运行结果:两次打印person的地址值是同样的,即调用完change() 方法以后,person变量并无发生改变。class

内存示意图

当执行到第3行代码时,程序在堆内存中开辟了一块内存空间,用来存储Person类的实例对象,同时在栈内存空间中开辟了一个存储单元,用来存储该实例对象的引用,person指向的存储单元。 按 当执行到第5行代码时,person做为参数传递给change()方法,须要注意的是:person将本身的存储单元的内容传递给了change()方法中的p变量。在change()方法中对p的一切操做都是针对p所指向的存储单元,与person所指向的那个存储单元没有关系了!变量