Java 值传递和引用传递

Java中的值传递和引用传递

从代码例子中思考

//例1
1 public void method1(){
2    int x=0;
3    this.change(x);
4    System.out.println(x);
5 }

6 public void change(int i){
7    i=1;
8 }

很显然的,在mothod1中执行了change(x)后,x的值并不会因为change方法中将输入参数赋值为1而变成1,也就是说在执行change(x)后,x的值z依然是0。这是因为x传递给change(int i)的是值。这就是最简单的传值。
进行一点变化的例2

//例2
1  public void method1(){
2    StringBuffer x=new StringBuffer("Hello");
3    this.change(x);
4    System.out.println(x);
5 }

6 public void change(StringBuffer i){
7    i.append(" world!");
8 }

看起来没什么变化,但是这次mothed1中执行了change (x)后,x的值不再是"Hello"了,而是变成了"Hello world!"。这是因为x传递给change(i)的是x的引用。这是最经典的传引用。
似乎有些奇怪了,两段程序没有特别的不同,可是为什么一个传的是值而另一个传的是引用呢?

让我们从内存的存储方式看一下x和I之间到底是什么关系。

  在执行到第2行的时候,变量x指向一个存放着int 0的内存地址。

  变量x---->[存放值0]

  执行第3行调用change(x)方法的时候,内存中是这样的情形:x把自己值在内存中复制一份,然后变量i指向这个被复制出来的0。

  变量x---->[存放值0]
                    ↓进行了一次值复制
  变量x---->[存放值0]

  这时候再执行到第7行的时候,变量i的被赋值为7,而这一步的操作已经跟x没有任何关系了。

  变量x---->[存放值0]
         
  变量x---->[存放值7]

再看例2

  变量x---->[存放值"Hello"]
  接下来执行第三行change(x),注意,这里就与例1有了本质的不同:调用change(x)时,变量i也指向了x指向的内存空间,而不是指向x的一个拷贝。

  变量x \
          -->[存放值"Hello"]
  变量x /

  于是,第7行对i调用append方法,改变i指向的内存空间的值,x的值也就随之改变了。

  变量x \
          -->[追加为"Hello World!"]
  变量x /

对于参数传递,如果是简单数据类型,那么它传递的是值拷贝,对于类的实例它传递的是类的引用。

再看一个例子:

1 void method1() {
    2 StringBuffer x = new StringBuffer("Hello");
    3 change1(x);
    4 System.out.println(x);
5 }
6
7 void method2() {
    8 StringBuffer x = new StringBuffer("Hello");
    9 change2(x);
    10 System.out.println(x);
11 }
12
13 void change1(StringBuffer sb) {
    14 sb.append(" world!");
15 }
16
17 void change2(StringBuffer sb) {
    18 sb = new StringBuffer("hi");
    19 sb.append(" world!");
20 }

调用method1(),屏幕打印结果为:“Hello world!”,调用method2(),我们认为结果应该是"hi world",因为sb传进来的是引用。可是实际执行的结果是"Hello"!

现在分析一下调用change2()

  程序执行到第8行,x指向一个存放着"Hello"的内存空间。
  变量x---->[存放值"Hello"]
  第9行调用change2,将sb指向x指向的内存空间,也就是传入x的引用。
  变量x \
          -->[存放值"Hello"]
  变量x /
  到这里为止还没有什么异样,接下来执行18行,这里就出现了类似传入值拷贝的变化:new 方法从内存中开辟了一块新的空间存放串"hi",同时sb指向了这块空间。
  变量x---->[存放值"Hello"]
  x原有的引用被切断;
  变量x---->[另一块存放"hi"的空间],接下来再对sb进行append已经和x没有任何关系了。

对于引用传递,如果对参数进行了重新赋值,new 方法改变sb指向内存的内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值