传值还是传引用

概述

     java应用程序在赋值操作或传参时,传值还是传引用是一个必须考虑的问题。借鉴他人的研究成果,再结合自己的实践总结,写下了这篇文章,自己备忘的同时希望也能给他人参考,欢迎指出错误或不足。

规则

1.在赋值时:

    a 传值:.8种基本类型(byte short int long char float double boolean)及其包装类(Byte Short Integer Long Character Float Double Boolean)

    b 传引用:class type、interface type 、arrary type、null type

2.在传参时:

 a.java有且只有一种参数传递机制——按值传递

 b.传容器时,在方法内无法更改实参(容器的引用),但可以更改容器中的元素值。

源码:

public class Test {
    int testId;

    /**
     *  赋值测试1
     */
    static void test1(){
        // 基本类型
        int i1 = 1;
        int i2 = i1;
        i2 = 2;
        System.out.println("i1=" + i1 + ";  i2=" + i2);
        //输出:i1=1;  i2=2
        // 包装类型
        Integer integer1 = 1;
        Integer integer2 = integer1;
        integer2 = 2;
        System.out.println("integer1=" + integer1 + ";  integer2=" + integer2);
        //输出:integer1=1;  integer2=2
    }

    /**
     * 赋值测试2
     */
    static void test2(){
        Test t1 = new Test();
        t1.testId = 1;
        Test t2 = t1;
        t2.testId = 2;
        System.out.println("t1.testId=" + t1.testId + ";  t2.testId=" + t2.testId);
        //输出:t1.testId=2;  t2.testId=2
    }

    /**
     *传参测试
     */
    static void swap(int[] p){
        // 交换
        int tmp = p[0];
        p[0] = p[1];
        p[1] = tmp;

        // 测试更改实参
        int [] j = {5,6};
        p = j;
    }

    public static void main(String[] args){
        test1();
        test2();

        int[] i = {1,2};
        swap(i);

        System.out.println("i[0]=" + i[0] + ";  i[1]="+i[1]);
        //输出:i[0]=2;  i[1]=1
    }
}

分析:

1.基本类型是基本类型不是面向对象的,主要出去效率方面的考虑,但是同时也提供基本类型的对象版本,即基本类型的包装器(wrapper)。采用传值而不采用传引用的方式可以理解。

2.对于最后一个输出,从存储结构上来看,数组i[2]存储在两个区:


  栈区                                                            堆区



从上图中发现,i、p作为实参、形参,在保存在栈区中,而数组具体内容保存在堆区。

调用方法时p获得数组在堆区的索引,此次过程传值,因此对p进行赋值操作实际上不影响i;然而对于堆区的部分,p、i具有相同的操作权限。





 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章