Java 值传递

当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?  

答案基本上是:值传递

说明:得出这种结论的前提必须是参数的值就是对该对象的引用,而不是对象的内容” 

----------------------------------------------------

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

引用传递:也称为传地址。方法调用时,实际参数的引用(即地址,而不是参数的值)被传递给方法中相对应的形式参数,

在方法中执行对形式参数的操作实际上就是对实际参数的操作(地址操作),这样方法执行中形式参数值的改变将会影响实际参数的值。

 

1.      基本类型传递

基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的, 值都存在栈中。

public class Other {

        public static void main(String[] args) {

                     int a = 1;

                     method(a);

                     System.out.println(a);

                  

        }

 

        public static void method( int a){

             a = 2;

        }

}

输出: a = 1;

2.      类传递

Case 1:

public class Other {

        public static void main(String[] args) {

            StringBuffer s = new StringBuffer("abc");

            method(s);

            System.out.println(s);          

        }

        public static void method(StringBuffer s){

             s = new StringBuffer("abc");

             s.append("d");

        }

}

输出:abc

解析:这时传递的是对象的地址,方法中的s又重新创建了对象“abc”,这时他们引用两个不同堆内存。s.append是在method创建出的“abc”上加“d”,所以会main中不会变。

 

Case 2:

public class Other {

        public static void main(String[] args) {

             StringBuffer a = new StringBuffer(“abc”);

             method(a);

             System.out.println(a);

        }

        public static void method( StringBuffer a){

             a.append(“d”);

        }

}

输出:abcd

解析:这时传递的是对象的地址,方法中的s同样指向 mains的指向“abc”, s.append是将“abc”加上“d,method直接修改这个值,所以会main中也跟着变。

 

Case 3:

public class Other {

        public static void main(String[] args) {

                    

                     String s = new String("abc");

                     method(s);

                     System.out.println(s);

                    

        }

 

        public static void method(String s){

             s = s+"d";

        }

}

输出:abc

在方法中改变String值,我画出的图如下:


因为在a的值是个地址。所以传的值也就是0x0001,然后方法中的a也指向堆内存的“aaa”。当a=bbb”时,方法区中的a 指向0x0002所以main中的a 还是不变的。与case2不同的是String是不可变的,s+”d”是将存有abc的字符数组的值取出再加上d. 总之一定不是在原有的“aaa”上进行操作,这牵扯到String的安全性设计。

3.      数组传递

public class Other {

 

    public static void main(String[] args) {

        int[] a = new int[] { 1, 2 };

        method(a);

        System.out.println(a[0]);

    }

 

    public static void method(int[] a) {

        a[0] = 0;

    }

}

输出:2

数值为什么会改变呢,我画了如下的堆栈图。

 

因为数组的地址和数组中值的地址中间又多了一道。传递到Method的b是main中b的值,也就是数组在堆中的地址0x0003,然后在这个数组中,第一个值又指向堆中的数值1,也就是0x0004 这时method 做b[0]=0,也就是把 数组中的第一位由0x0004改成0x0006,直接操作了该数组。

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页