java中的方法到底是值传递还是引用传递,答案:值传递。 但是,当传递的参数为引用类型时(如传递一个对象),如果在方法中改变了参数,那么有可能改变原来的数据,这就表现的像引用传递。这是为什么呢?关键还是在于内存中对象的存储与基本类型数据的存储不同,内存中并不直接存储对象的内容,而是在栈内存中存储它的地址,然后在堆内存中存储内容,在参数传递时,是将对象在栈内存中的值(及地址)复制后进行的传递,所以可能影响原数据。

 

public class Demo04 {
    //java中的方法到底是值传递还是引用传递,答案:值传递。

    //但是,当传递的参数为引用类型时(如传递一个对象),如果在
    //方法中改变了参数,那么有可能改变原来的数据,这就表现的像
    //引用传递。这是为什么呢?关键还是在于内存中对象的存储与基本类型
    //数据的存储不同,内存中并不直接存储对象的内容,而是在栈内存中存储
    //它的地址,然后在堆内存中存储内容,在参数传递时,是将对象在栈内存中
    //的值(及地址)复制后进行的传递,所以可能影响原数据。

    public static void main(String[] args) {
        //案例一:传递的参数为基本类型
        int a = 2;

        System.out.println("============");
        System.out.println(a);

        changeInt(a);

        System.out.println("============");
        System.out.println(a);//输出结果仍然为2,说明方法中的赋值不影响原数据。

        //案例二:传递的参数为引用类型,如Int类型的数组、自定义类的对象等
        int[] ints = new int[2];

        System.out.println("============");
        System.out.println(ints[0]);

        changArray(ints);

        System.out.println("============");
        System.out.println(ints[0]);//输出的结果为2,方法中的赋值改变了原数据,但仍为值传递

        //案例三:传递的参数为引用类型时,虽然有点像引用传递,但还是不同,如下:
        System.out.println("============");
        System.out.println(ints[0]);

        changeArray2(ints);

        System.out.println("============");
        System.out.println(ints[0]);//输出的结果为0,如果是引用传递则输出结果应为2。好好体会吧哈哈

        //案例四:传递参数为String类型的时候,方法中的赋值对原数据无影响,这是为啥,自己查吧。
        String str = "Hello world!";

        System.out.println("============");
        System.out.println(str);

        changeString(str);

        System.out.println("============");
        System.out.println(str);//输出的结果仍为Hello world!,方法中的赋值对原字符串无影响的。
    }

    //当传递的参数为基本类型的时候为值传递
    public static void changeInt(int a) {
        a = 3;
    }

    //当传递的参数为对象的时候仍为值传递,但对象的值为它的地址,所以值传递也可能对结果产生影响
    public static void changArray(int[] ints) {
        ints[0] = 2;
    }

    //当传递的参数为对象时,是将值的地址复制了一遍后传递的地址的副本,和引用传递中直接传值还是不同的
    public static void changeArray2(int[] ints) {
        ints = new int[2];
        ints[0] = 2;
    }

    //当传递的参数为String类型的时候,方法中的操作对原字符串无影响
    public static void changeString(String str) {
        str = "Fxxk the world!";
    }

    //当传递的参数为引用类型的时候仍为值传递,只是传递的值为对象,如
    //传递参数ints时,传递的就是对象ints的值[I@10f87f48(对象位于栈内存中的值),
    //而由于对象在栈内存中的值是一个地址,指向它的堆内存(存放真实数据的地方),
    //所以虽说是值传递,传递的也确实是对象的值,但其实传递的是一个地址,它的效果和
    //引用传递很像,但是本质还是有区别:引用传递是将参数的地址直接传过去,
    //而上述的特殊的值传递,是将对象的地址复制了一份,然后将复制后的地址传过去。
}