java中的参数传递

今天在写代码的时候,遇到一个现象,一个数组作为参数传递到函数中,在函数中改变了这个参数的的值,结果原来的数组的值也改变了。。。
如下代码:

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] datas = new int[] { 1, 2, 3, 4, 5 };
        change(datas);
        for (int a : datas) {
            System.out.print(a + " ");
            //输出结果:0 2 3 4 5
            //很明显,值改变了 
        }
    }

    private static void change(int datas[]) {
        datas[0] = 0;
    }
}

在我的印象中,传递的参数不是一个拷贝吗?这个拷贝发生变化怎么会影响原来的值呢?于是去查找了各方资料,终于找到了答案。。。

原来:
在Java中,只有值传递,没有引用传递,而且传递的都是原来的一个拷贝,对于基础类型很好理解,传递的参数只是该基础类型的值,在被调用的方法中无论怎么改变也不会影响原来的值。但是如果传递的是一个对象实例,那么参数的值就是传递的这个对象引用的一个拷贝,既然是引用的一个拷贝,那么它和原来对象的引用指向的是一个对象,所以在被调用的函数中对象的内容是可以改变的。但是如果改变了这个对象的引用,比如重新new一下,那么它就不再指向原来的对象,这样它的改变就不会影响到原来的对象。
例如:

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] datas = new int[] { 1, 2, 3, 4, 5 };
        System.out.println("datas....创建时...." + datas);
        change(datas);
        for (int a : datas) {
            System.out.print(a + " ");
            //输出0 2 3 4 5 
            //值发生了改变
        }
        System.out.println("\ndatas...调用函数后..." + datas);
    }

    private static void change(int datas[]) {
        datas[0] = 0;
        System.out.println("datas...函数中..." + datas);
    }
}

输出结果:

datas....创建时....[I@1a8fa0f0
datas...函数中...[I@1a8fa0f0
0 2 3 4 5 
datas...调用函数后...[I@1a8fa0f0

很明显它们输出的地址都是一样的,函数中的改变影响到了原来的值,不过函数中的参数只是一个拷贝。

比如这样:

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] datas = new int[] { 1, 2, 3, 4, 5 };
        System.out.println("datas....创建时...."+datas);
        change(datas);
        for (int a : datas) {
            System.out.print(a + " ");
        }
        System.out.println("\ndatas...调用函数后..."+datas);
    }

    private static void change(int datas[]) {
        datas = new int[]{0,0,0};
        System.out.println("datas...函数中..."+datas);
    }
}

运行结果:

datas....创建时....[I@8094cc7
datas...函数中...[I@1a8fa0f0
1 2 3 4 5 
datas...调用函数后...[I@8094cc7

从运行结果来看,数组在调用函数时重新创建了一个对象,其值也发生了改变,但是并没有影响到原来的对象,因为传递的参数只是一个拷贝。

然后我又这样试了一下:

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String s = "abcd";
        System.out.println("s....创建时...." + s);
        change(s);
        System.out.println("s...调用函数后..." + s);
    }

    private static void change(String s) {
        s = "aaaa";
        System.out.println("s...函数中..." + s);
    }
}

运行结果:

s....创建时....abcd
s...函数中...aaaa
s...调用函数后...abcd

看到这个结果有点奇怪,为什么改变s的值,原来的值没发生改变呢?
猜想应该是这样:
s = “aaaa”;其实又创建了一个对象,和原来的已经不一样了。。。
于是验证了一下。。。

public class Test {

    static String s;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        s = "abcd";
        change(s);
    }

    private static void change(String s1) {
        s1 = "aaaa";
        System.out.println((s1 == s));
        //输出结果:false
    }
}

从运行结果看来s1和s并不相等,看来猜想是正确的。
不过为什么s1=”aaaa”重新创建了一个对象呢?什么情况下才会创建对象呢?
继续学习中。。。

注:Java中的数组是对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值