Java函数传参 Java引用和C++引用的区别

       先说Java引用和C++的引用的区别,这是两个不同的概念,Java中的引用更像是C++中的指针,并且它是安全的,Java的引用不能指向空对象,而C++却允许野指针的存在;C++中的引用只不过是变量的别名,实际就代表变量自身,内部实现相当于一个指针变量,与指针的实现方式类似。C++引用的内存单元保存的是指向变量的地址,与指针不同地方是,引用在定义时必须初始化,而且使用过程中,引用变量保存的内存单元地址值是不能改变的。

       接下来主要分析Java的中函数传参,很多地方都在问Java的函数传参传的到底是值还是引用,两种说法都不准确,传递的实际上是实参值的副本,如果实参是个基本数据类型比如int,char那传的就是int,char的副本,如果实参是个引用数据类型,那传的就是个引用副本,还是拿经典的swap说明吧

//例一:
public class Test {

    public static void swap(int a, int b) {
        System.out.println("形参a = " + a + " 形参b = " + b);
        int tmp = a;
        a = b;
        b = tmp;
        System.out.println("形参a = " + a + " 形参b = " + b);
    }

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

//结果:
实参a = 10 实参b = 20
形参a = 10 形参b = 20
形参a = 20 形参b = 10
实参a = 10 实参b = 20

 

//例二:
public class Test {

    public static void swap(Integer a, Integer b) {
        System.out.println("形参a = " + a.intValue() + " 形参b = " + b.intValue());
        Integer tmp = a;
        a = b;
        b = tmp;
        System.out.println("形参a = " + a.intValue() + " 形参b = " + b.intValue());
    }

    public static void main(String[] args) {
        Integer a = new Integer(10);
        Integer b = new Integer(20);
        System.out.println("实参a = " + a.intValue() + " 实参b = " + b.intValue());
        swap(a, b);
        System.out.println("实参a = " + a.intValue() + " 实参b = " + b.intValue());
    }
}

//结果:
实参a = 10 实参b = 20
形参a = 10 形参b = 20
形参a = 20 形参b = 10
实参a = 10 实参b = 20

例一和例二的区别在于一个实参是基本数据类型,一类是引用数据类型,可以看到它们都只是交换了形参而没有交换实参,可能有人奇怪为什么传引用没法完成交换,首先正如之前所说Java的引用和C++的引用完全不是一个概念,a和b是分别指向整型对象10和整型对象20的两个引用,传递后的形参可以理解为a'和b',他们也是两个指向整型对象10和整型对象20的引用,且是a和b的副本,也就是说这时候整型对象10和20都分别有两个引用指向它们,方法内部交换的是两个副本引用,引用指向的实际对象的值并没有交换, 那如何才能交换?

最简单办法是传数组进去,首先要明确,数组存放在java内存中的堆区,而指向其的引用在栈区。某篇博客中的原话:Java的方法参数只是传值,引用作为参数使用时,会给方法内引用的值的COPY,所以在方法内交换两个引用参数是没有意义的,因为方法交换的是参数的COPY值;但是在方法内改变一个引用参数的属性是有意义的,因为引用参数的COPY值指向的对象和原引用指向的是同一个对象。

//例三:
public class Test {

    public static void swap(Integer[] nums, int a, int b) {
        System.out.println("形参a = " + nums[a] + " 形参b = " + nums[b]);
        int tmp = nums[a];
        nums[a] = nums[b];
        nums[b] = tmp;
        System.out.println("形参a = " + nums[a] + " 形参b = " + nums[b]);
    }

    public static void main(String[] args) {
        Integer[] nums = new Integer[2];
        nums[0] = new Integer(10);
        nums[1] = new Integer(20);
        System.out.println("实参a = " + nums[0] + " 实参b = " + nums[1]);
        swap(nums, 0, 1);
        System.out.println("实参a = " + nums[0] + " 实参b = " + nums[1]);
    }
}

//结果:
实参a = 10 实参b = 20
形参a = 10 形参b = 20
形参a = 20 形参b = 10
实参a = 20 实参b = 10

或者重新定义一个number类,然后交换类的成员变量的值

public class Test {

    static class myNum {
        int a;

        myNum(int aa) {
            a = aa;
        }

        int getNum() {
            return a;
        }

        void setNum(int aa) {
            a = aa;
        }
    }
    public static void swap(myNum a, myNum b){
        System.out.println("形参a = " + a.getNum() + " 形参b = " + b.getNum());
        int tmp = a.getNum();
        a.setNum(b.getNum());
        b.setNum(tmp);
        System.out.println("形参a = " + a.getNum() + " 形参b = " + b.getNum());
    }

    public static void main(String[] args) {
        myNum a = new myNum(10);
        myNum b = new myNum(20);
        System.out.println("实参a = " + a.getNum() + " 实参b = " + b.getNum());
        swap(a, b);
        System.out.println("实参a = " + a.getNum() + " 实参b = " + b.getNum());
    }
}

//结果:
实参a = 10 实参b = 20
形参a = 10 形参b = 20
形参a = 20 形参b = 10
实参a = 20 实参b = 10


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值