JavaSE 之 ----- Java中只有值传递

来源:互联网 发布:mac 视频压缩工具 编辑:程序博客网 时间:2024/05/18 03:27



说实话,之前一直没有去关注这个问题,最近撸代码才发现这个易错的问题:Java中究竟怎样就是值传递?怎样又是引用传递?


这里给出结果:Java中只有值传递 !常说的引用传递不过是值传递的一种类型罢了!

值传递,意味着传递给方法形参的其实都是副本,并非把真值传递到方法中。


为什么说Java中只有值传递?

常说的值传递:各类基本数据类型变量的传递,只是传递了一个复制了原始值的副本值,在方法内修改形参并不影响原始值;

常说的引用传递:对象引用变量的传递或者各种数组变量的传递(偶尔说的整个数组作为参数传递),只是传递了一个复制了原始引用的副本引用,意思就是说,两个引用指向的都是原始对象,在方法内部修改形参并不影响原始对象,注意,这里说的修改形参是指对形参引用重新赋值等与原始对象无关的操作,想想看,如果利用形参引用修改了对象的某些域值,自然原对象就变化了。


回过头来看,常说的值传递跟Java只存在值传递很符合,常说的引用传递说白了就是传递了一个对象引用指向的对象地址的拷贝值,引用传递的其实就是对象的地制值(类似于两个指针都指向同一个对象),所以这种值传递其实传递的也是副本,只不过是地址的副本,所以也符合最初的观点。


至于实践验证就懒得写了,直接摘抄网上的小例子吧,搞清楚了自然就明白了:

***** 例 *****

public class Test{        String str = new String("good");    char[] ch = {'a','b','c'};    int i = 10;    public void change(String str,char[] ch,int i){            str = "test ok";        ch[0] = 'g';        i++;        }        public static void main(String[] args){            Test tt = new Test();        tt.change(tt.str,tt.ch,tt.i);        System.out.println(tt.i);        System.out.print(tt.str+" and ");        System.out.println(tt.ch);         }}
结果:

10

good and gbc

----- 分析 -----

str形参传递进来的只是一个String对象的引用,方法里str = "test ok"只是让传递进来的引用指向另外一个String值,但是并没有改变原来String对象的值(类似C++中改变指针的指向);

ch形参类似str,但是方法里ch[0] = 'g' 改变了指向的数组值;

i形参就完全是值副本了,不影响原值。

作为踩过坑的人,觉得最容易理解错的是认为赋值这一动作是改变原始值的动作,但是赋值只是改变了引用变量的指向对象,如果搞清楚"对象" 与 "对象引用",其实也是很好理解的。


***** 自测 *****

public class Test{        private String nn = new String("1");    private String[] mm = {"2","5"};        void test(String nn,String[] mm){                nn = new String("3");        this.nn = "9";                mm[0] = "4";        System.out.println("in test(),mm[0]: "+mm[0]);        mm = new String[]{"8","7"};        System.out.println("in test(),nn: "+nn);        System.out.println("this.nn: "+this.nn);        System.out.println("mm[0]: "+mm[0]);    }        public static void main(String[] args){                Test s = new Test();        s.test(s.nn,s.mm);        System.out.println(s.nn+"  "+s.mm[0]);    }}

如果自己知道的结果跟编译运行出来的结果一样则说明这个坑不会再踩了





1 0
原创粉丝点击