现在的位置: 首页 > 综合 > 正文

Java传值还是传引用

2014年02月28日 ⁄ 综合 ⁄ 共 1458字 ⁄ 字号 评论关闭

Ref: http://ivan-pig.iteye.com/blog/422891
一.预备知识 

     在Thinking in Java的第二章里,提到了Java将
对象存放到了哪里。这里主要看栈和堆。 

     看下面几行代
码的区别。 
Java代码 

    int i = 1;  
    String str = new String("Hello");  

     从第二行代码里又可以引申如一个经典的面试题,这里创建了几个String对象。这里不做讨论。 

     大家都知道左
边的是引用,指向了右边的实际的值。但是在Java里面这两段有区别吗?看图。 
图上可以看出,栈里的每个值又可以看成是一个个的键值对。 
    对于 
Java代码 

  1. int i = 1;  

    来说,键就是变量i,而值就是1。 

    而
对于 
Java代码 

  1. String str = new String("Hello");  

    来说,键是变量str,而值是new String("Hello");在堆里的地址。(在Java中所有new出来的东东都在堆里面) 

     二.
传值还是传引用? 

     好,知道了上面的区
别,对于传值和传引用的理解就很有帮助了。 

     看下面的代
码。 
Java代码

    public class Change {  
        public void change(int i){  
            i = 2;  
        }  
        public void change(String str){  
            str = "Ivan";  
        }  
    
        public void change(StringBuffer str){  
            str.append(" World");  
        }  

     那么将上面的i和str传入如下的三个方法中是否有作用呢?(这里添加了一个StringBuffer,是因为你无法改变String) 
     再来看下Java中的方法如何执行的。在Thinking in Java第七章中,提到了一点。方法的执行是将参数压入栈中,跳至方法代码处执行方法,然后跳回并清理栈中的参数,处理返回值。这里可以知道,方法的参数在栈里面也有对应的存储空间,而值就是传入的i和str在栈中所对应的值。也就是说,是i和str的一个拷贝。 

     那么来看上面的三个方法。 

    
对于第一个方法,从上面可以知道,这里的i和原来的i已经不是同一个i了,所以这里操作的是完全不同的东东。 

     第二个方法和第一个相似,根据前面知道,
这里的str持有的是指向"Hello"的引用。但是这里直接将这个引用改成了指向"Ivan"的,原来的str还是指向"Hello",对原来的str没有一点影响。 

     第三个方法是是直接操作了str所指向的那个"Hello",因
为原来的str指向同样的"Hello",所以这就会改变原来str的值了。 


    三.
总结 

    从上面可以知道,Java是将
栈里的值拷贝了一份作为参数传到了方法里面。对于基本类型就是传的值了,而对于对象类型就是引用了。不管传的是值还是引用,都是栈里的拷贝。记住这一点应该就不会再有什么疑问了


    四.关于数
 

   
继续看Thinking in Java,关于数组一节的介绍,有这么一句。论使用的是哪种类型的数组,数组标示符其实只是一个引用,指向在堆中创建的一个真实对象,这个(数组)对象用以保存指向其他对象的引用。 

    再
结合上面的内容,下面两个方法能否改变值应该能知道吧

public void change(int[] i){  
        i[0]=1;  
    }  
    public void change(String[] str){  
        str[0]="Ivan";  
    } 

抱歉!评论已关闭.