Java下的值传递和引用传递区别以及swap函数的四种实现方式

Java中的值传递和引用传递

C和Java使用参数传值是用其实参值来进行初始化形参的值。对于基本变量,C和C++允许显式传递变量的地址(引用传递),在scanf函数中的参数前面的&地址符可以见得。而Java不允许这样做,因为Java对普通类型变量不支持引用传递Java的方法传递只有值传递一种,即将实际的参数值的副本传入方法,而参数不受影响

所以我们写一个测试代码来试验一下:

package test;
class testObj{
    private int m = 1;
    private String s = "测试obj";
    void setM(int m) {
        this.m = m;
    }
    void setS(String s){
        this.s = s;
    }
    String getS(){
        return s;
    }
}
public class test {
    private static void inttest(int n){
        System.out.println(n++);
    }
    private static void testobj(testObj n){
        n.setS("testobj");
    }
    private static void teststring(String[] s){
        s[0] = "teststring";
}
    public static void main(String[] args){
        int n = 0;
        test t = new test();
        testObj to = new testObj();
        to.setS("mainobj");
        to.setM(10);
        String[] str = new String[]{"mainstring"};
        test.inttest(n);
        test.testobj(to);
        test.teststring(str);
        System.out.println(n);
        System.out.println(to.getS());
        System.out.println(str[0]);
    }
}

可以看到结果是普通的int值传递没有改变,而实例化对象和特殊类型String(数组)都发生了改变。因此可以得出结论:变量进行值传递相当于复制一个副本,当然彼此之间没有关系;而引用传递相当于指向的同一个内存地址,任意一个操作都将影响实际对象。对于String这些特殊的不可操作类要特殊对待作为引用类型操作。
在这里插入图片描述

Java中Swap交换函数

在C/C++里面交换值的方法:

void swap(int&a ,int&b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}

而Java中交换:使用C中的引用参数进行的上述交换在Java中不起作用,因为Java没有这些类型的参数。

通过数组交换

但是通常应用程序实际上只需要交换数组中的两个值。在这种情况下,可以传递数组和两个索引以交换为三个参数。这种方法用在算法中比较多如冒泡算法。

private static void swap(int[] Arr,int a, int b){
        int temp = Arr[a];
        Arr[a] = Arr[b];
        Arr[b] = temp;
    }
public static void main(String[] args){
        int[] Arr = new int[]{1,2,3,4,5};
        int a = 0;
        int b = 1;
        swap(Arr,a,b);
        System.out.println(Arr[0]);
        System.out.println(Arr[1]);
    }

利用类变量传值

Java对于引用类型的参数传递一样采用了值传递。

    private static void swap(DataWrap dw){
        int temp = dw.a;
        dw.a = dw.b;
        dw.b = temp;
        System.out.println("swap中的顺序: " + " a: " + dw.a + " b: " + dw.b);
    }

    public static void main(String[] args){
        DataWrap dw = new DataWrap();
        dw.a = 1;
        dw.b = 2;
        System.out.println("之前的顺序: " + " a: " + dw.a + " b: " + dw.b);
        swap(dw);
        System.out.println("之后的顺序: " + " a: " + dw.a + " b: " + dw.b);
    }

利用包装器类

static class MyInteger {
    private int x;                   // single data member
    public MyInteger(int xIn) { x = xIn; } // constructor
    public int getValue() { return x; }  // retrieve value
    public void insertValue(int xIn) { x = xIn;} // insert
}

    public static class Swapping {
        // swap: pass references to objects
        static void swap(MyInteger rWrap, MyInteger sWrap) {
            // interchange values inside objects
            int t = rWrap.getValue();
            rWrap.insertValue(sWrap.getValue());
            sWrap.insertValue(t);
        }

        public static void main(String[] args) {
            int a = 23, b = 47;
            System.out.println("Before. a:" + a + ", b: " + b);
            MyInteger aWrap = new MyInteger(a);
            MyInteger bWrap = new MyInteger(b);
            swap(aWrap, bWrap);
            a = aWrap.getValue();
            b = bWrap.getValue();
            System.out.println("After.  a:" + a + ", b: " + b);
        }
    }

利用外部内联的方式

class Exchange{ 
	int i , j; 
	Exchange(int i, int j){ 
	this.i = i; 
	this.j = j; 
	}
	public void swap(Exchange exc)
	{ 
		int temp = exc.i; 
		exc.i = exc.j;
		exc.j = temp; 
	} 
 }
public class TestSwap { 
	static int a = 3; 
	static int b = 2;
	public static void main(String[] args){ 
		Exchange exc = new Exchange(a,b); 
		System.out.println("before swap "+"a的值="+a+" b的值="+b); 
		exc.swap(exc); 
		a=exc.i;
		b=exc.j;
		System.out.println("after swap "+"a的值="+a+" b的值="+b);
	} 
} 


发布了15 篇原创文章 · 获赞 21 · 访问量 3372

猜你喜欢

转载自blog.csdn.net/Dragonpigz/article/details/104155977
今日推荐