zoukankan      html  css  js  c++  java
  • Java中的值传递和引用传递

    对象传递(数组、类、接口)是引用传递,原始类型数据(整型、浮点型、字符型、布尔型)传递是值传递。

    那么什么是值传递和应用传递呢?

    值传递是指对象被值传递,意味着传递了对象的一个副本,即使副本被改变,也不会影响源对象。(因为值传递的时候,实际上是将实参的值复制一份给形参。)

    引用传递是指对象被引用传递,意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象的改变会反映到所有的对象上。(因为引用传递的时候,实际上是将实参的地址值复制一份给形参。)

    值传递和应用传递实例

    1. 值传递

    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 20;
    
        swap(num1, num2);
    
        System.out.println("num1 = " + num1);
        System.out.println("num2 = " + num2);
    }
    
    public static void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
    
        System.out.println("a = " + a);
        System.out.println("b = " + b);
    }

    结果:

    a = 20
    b = 10
    num1 = 10
    num2 = 20
    

    解析:在swap方法中,a、b的值进行交换,并不会影响到num1、num2。因为,a、b中的值,只是从num1、num2的复制过来的。 也就是说,a、b相当于num1、num2的副本,副本的内容无论怎么修改,都不会影响到原件本身。

    2. 引用传递

    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
    
        change(arr);
    
        System.out.println(arr[0]);
    }
    
    public static void change(int[] array) {
    //将数组的第一个元素变为0
        array[0] = 0;
    }

    结果:

    0
    

    解析:无论是主函数,还是change方法,操作的都是同一个地址值对应的数组。 。因此,外部对引用对象的改变会反映到所有的对象上。

    一些特殊的例子

    1. StringBuffer类型传递

    	// 测试引用传递:StringBuffer
    	@org.junit.Test
    	public void method1() {
    		StringBuffer str = new StringBuffer("AAAAAAAAAAAAAAAAAAAAAAAAA");
    		System.out.println(str);
    		change1(str);
    		System.out.println(str);
    	}
    
    	public static void change1(StringBuffer str) {
    		str = new StringBuffer("BBBBBBBBBBBBBBBBBBBBBBBB");
    	}

    结果:

    AAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAA

    解析:

    很多要这个时候要问了:StringBuffer创建的明明也是对象,那为什么输出结果依然是原来的值呢?

    因为在change1方法内部我们是新建了一个StringBuffer对象,所以str指向了另外一个地址,相应的操作也同样是指向另外的地址的。

     public static void change1(StringBuffer str) {

    		str.append("CCCCCCCCCCCCCCCCC");
    		str.insert(3, "(DDDDDDDDDDDD)");	
    	}
    

    2. String类型传递

    	public void method2() {
    		String str = new String("DDDDDDDDDDDDDDDDDDDDDDDDDDDD");
    		System.out.println(str);
    		change2(str);
    		System.out.println(str);
    	}
    
    	public static void change2(String str) {
    		// str="EEEEEEEEEEEEEEEEEEEEEEEEEEEE";
    		str = new String("EEEEEEEEEEEEEEEEEEEEEEEEEEEE");

        }

    结果:

    DDDDDDDDDDDDDDDDDDDDDDDDDDDD
    DDDDDDDDDDDDDDDDDDDDDDDDDDDD

    可以看到不论是执行str="abc;"还是str = new String("abc");str的输出的值都不变。 按照我们上面讲“StringBuffer类型传递”的时候说的,str="abc;"应该会让str的输出的值都不变。为什么呢?因为String在创建之后是不可变的。

    3. 一道类似的题目

    下面的程序输出是什么?

    public class Demo {
    	public static void main(String[] args) {
    		Person p = new Person("张三");
    
    		change(p);
    
    		System.out.println(p.name);
    	}
    
    	public static void change(Person p) {
    		Person person = new Person("李四");
    		p = person;
    	}
    }
    
    class Person {
    	String name;
    
    	public Person(String name) {
    		this.name = name;
    	}
    }

    很明显仍然会输出张三。因为change方法中重新创建了一个Person对象。

    那么,如果把change方法改为下图所示,输出结果又是什么呢?

    	public static void change(Person p) {
    		p.name="李四";
    	}

    输出结果为 李四

  • 相关阅读:
    string基本字符系列容器(一)
    HDU 1541 star (树状数组)
    NKOI 1321--数列操作问题(裸BIT)
    树状数组(BIT)初学
    vector向量容器
    C++ STL概述
    2015年,为ACM奋斗的一年
    kuangbin带你飞,矩阵(简单数学推导题)
    hust 1009 Sum the K-th
    hust 1223 Friends
  • 原文地址:https://www.cnblogs.com/mr-wuxiansheng/p/9443727.html
Copyright © 2011-2022 走看看