引言

我们都知道在c语言或者c++中都有指针这个概念,所以我们在向函数中传递参数的时候可以选择传或者传,但是在Java中没有了指针的概念,我们在写一个方法交换两个数的时候怎么办;

public class Main {
    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        swap(a, b);
    }
    
    public static void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
    }
}

在Java中没有了指针我们要怎么样将地址传进去,上述这个代码很显然是达不到要求的,这个我们在c语言刚入门就知道了;

Java对象

我们先来说说Java中对象的内存是怎么分配的,我们就以数组举例:

int[] arr = new int[5];

我们用一张图来说说对象的内存是在什么地方;

java中交换两个数的库函数_数组


jvm中也有内存的堆和栈,程序的局部变量都会放在栈区中,对象都会在堆区,当我们创建一个对象的时候就会在堆区创建,在栈区保存对象的地址;上面的数组创建以后就会是下图所示;

java中交换两个数的库函数_数组_02


arr[0], arr[1].....里面也可以放着一些类对象,但是基本数据类型不同啊,他们不具备对象的特性,他们不可能在堆区开辟空间,那怎么样才能把这些转换成对象呢;

包装类

为了解决8种基本数据类型不能被当成Object类型变量使用的问题,Java提供了包装类的概念;
除了int的包装类是Integerchar的包装类是Character以外别的类型的包装类都是将其首字母大写即可;
所以上面的问题我们可以这样解决:

public class Main {
    public static void main(String[] args) {
        Integer a = 1;
        Integer b = 2;
        swap(a, b);
        System.out.println(a + " " + b);
    }

    public static void swap(Integer a, Integer b) {
        Integer temp = a;
        a = b;
        b = temp;
    }
}

这样真的可以了吗?

答案是不可以!!!!
java的参数传递分为两种,基本类型和String,是传值,这样函数内部的改变与外部参数无关。

数组以及类的实例,是传引用,在函数内部对该引用的操作可以影响到外部参数,但是无法将该引用赋值对象的改变传递到函数体外。

public class Main {
    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        MyObject aObject = new MyObject(a);
        MyObject bObject = new MyObject(b);
        swap(aObject, bObject);
        a = aObject.getVaule();
        b = bObject.getVaule();
        System.out.println(a + " " + b);
    }

    public static void swap(MyObject a,  MyObject b) {
        int t = a.getVaule();
        a.setVaule(b.getVaule());
        b.setVaule(t);
    }
}

public class MyObject {
    private int vaule;

    public MyObject(int vaule) {
        this.vaule = vaule;
    }

    public void setVaule(int vaule) {
        this.vaule = vaule;
    }

    public int getVaule() {
        return vaule;
    }
}

也可以用数组不过最后出了个方法还是要给a,b赋值不如就老老实实在主方法里写三行代码;