Java的值传递和引用传递

行参和实参
行参:方法在被调用的时候需要传递进来的参数。如function(int a)中的参数a,只有在方法被调用的时候a才有意义。
实参:方法在被调用时,实计被传入的值。在方法被调用前已经被初始化。
JAVA中基本类型和引用类型
基本类型:byte、short、int、long、float、double、char、boolean
引用类型:类,数组等
值传递和引用传递
把实参的值赋值给行参,那么对行参的修改不会影响实参的值
把实参的地址传递给行参,行参和实参是同一个对象,只是名字不同,对行参的修改会影响实参的值。

下面我们先来看一看基本类型的操作:

 public static void main(String[] args) {
        int a=1;
        System.out.println("a="+a);
        func(a);
        System.out.println("a="+a);
    }
    private  static void func(int a){
        a=10;
    }

输出结果为:

a=1
a=1

通过上面的结果可以看出,对于基本类型的数据,在实参传入形参时,都是值传递,而不是内容本身。

下面我们来看看引用类型的操作:

   public static void main(String[] args) {
       P p=new P();
       p.setName("芃兮贝贝");
       System.out.println(p.getName());
       func(p);
       System.out.println(p.getName());
    }
    private  static void func(P p){
        p.setName("贝贝");
    }

输出结果为:

芃兮贝贝
贝贝

通过上面的结果可以看出在方法中对引用类型的行参进行修改,最后实参的值也被修改了。那么是不是可以得出结论:

java中基本类型是值传递,引用类型是引用传递呢?

接下来我们再看一个例子:

   public static void main(String[] args) {
       P p=new P();
       p.setName("芃兮贝贝");
       System.out.println(p.getName());
       func(p);
       System.out.println(p.getName());
    }
    private  static void func(P p){
        p=new P();
        p.setName("贝贝");
    }

这段代码比上面的代码是方法func中增加了一行: p=new P();
我们来看看结果:

芃兮贝贝
芃兮贝贝

奇怪,为什么这次实参的值没被修改呢?
其实,熟悉JVM的朋友们都知道,在JVM中对象是存储在堆内存中的,而且堆内存是共享的,而变量p的值只是一个堆内存的地址,当调用func时,把实参的值传给行参时,是传的一个内存地址,这个时候实参和行参是指向的同一个地址。这个时候如果对行参的修改自然实参也是读到修改后的内容。但是如果行参重新new了一个对象,这个时候JVM会在堆中重新创建内存块来存这个对象。这个时候行参和实参就是两个不同的内存地址了。现在对行参的修改自然是不会影响实参。

因此可见:在Java中所有的参数传递,不管基本类型还是引用类型,都是值传递,或者说是副本传递。

如果是对基本数据类型的数据进行操作,由于原始内容和副本都是存储实际值,并且是在不同的栈区,因此形参的操作,不影响原始内容。

如果是对引用类型的数据进行操作,分两种情况,一种是形参和实参保持指向同一个内存地址,则形参的操作,会影响实参指向的对象的内容。一种是形参被改动指向新的内存地址(如重新赋值引用),则形参的操作,不会影响实参指向的对象的内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值