纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

Java值传递 浅谈Java到底是值传递还是引用传递呢

XH雪浪风尘   2021-06-08 我要评论
想了解浅谈Java到底是值传递还是引用传递呢的相关内容吗XH雪浪风尘在本文为您仔细讲解Java值传递的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Java值传递,java传递下面大家一起来学习吧

一、前言

最近在看Java核心卷一也就是这本书:

在这里插入图片描述

在这本书里面也看到了这个问题Java是值传递还是引用传递这个问题其实也是很有意思的之前也看到过这个问题但是只是依稀记得是值传递而且网上也有在讨论这个问题的所以就先说结论吧:是值传递

二、值传递与引用传递

既然讨论是值传递还是引用传递那肯定是要知道啥是值传递、引用传递的

值传递:是指在调用函数时将实际参数复制一份传递到函数中这样在函数中如果对参数进行修改将不会影响到实际参数
引用传递:是指在调用函数时将实际参数的地址直接传递到函数中那么在函数中对参数所进行的修改将影响到实际参数

所以我们就可以做个简单的比较:

值传递 引用传递 
将参数复制一份传递过去 将参数的实际地址传递过去
不会影响到实际参数 会影响到实际参数

我们在方法中传递参数类型有两种:基本数据类型(数字、布尔)以及对象引用这两种所以我们就从这两种类型进行分析

三、基本数据类型

以数字int为例:

public class Test {
    public static void main(String[] args) {
        Test test=new Test();
        int i=1;
        test.incr(i);
        System.out.println("main中i的值大小为"+i);
    }
    public void incr(int i){
        i=i+1;
        System.out.println("incr中i为"+i);
    }
}

main方法中的结果要么为1要么为2如果还是1的话那么很大可能就是值传递我们看下输出结果:

incr中i为2
main中i的值大小为1

可以看到main方法中的值仍为1我们来看下这个的过程是怎么样的:

在这里插入图片描述

incr方法中虽然对i的值进行了加一操作但是他只是将值复制了一份incr方法执行完毕之后就会被处理掉并没有改掉原先的值所以才会在main方法中打印出i还是原先的值

四、对象引用

基本数据类型其实比较好解释对象引用其实还是有那么一点迷惑性的因为有的人可以认为对象引用是引用传递他可以向方法中传递一个对象然后在子方法中修改对象的值就比如下面的这个例子:
例子一:

public class Test {
    public static void main(String[] args) {
        Test test=new Test();
        Student s1=new Student();
        s1.setId(1);
        test.changeId(s1);
        System.out.println("main中的s1id是"+s1.getId());
    }

    public void changeId(Student student){
        student.setId(2);
        System.out.println("changeId中的id为"+student.getId());
    }
   
}
class Student{
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

一个很简单的例子创建个student对象只有id这一个字段将student对象传递到子方法中执行结果会是什么呢?

changeId中的id为2
main中的s1id是2

可以看到阿main方法与changeId方法中他们最后的id都是2所以有的人就会认为修改了对象中的值所以是值传递

其实我们看上面值传递与引用传递的概念引用传递是传递的地址那么我们就假设对象引用是引用传递方式那么我传递进去两个对象交换他们的位置是可以改变他们的指向的接下来我们就来看一下会不会改变:
例子二:

package com.dong.No2;

public class Test {
    public static void main(String[] args) {
        Test test=new Test();
        Student s1=new Student();
        Student s2=new Student();
        s1.setId(1);
        s2.setId(2);
        test.changeId2(s1,s2);
        System.out.println("main中的s1id是"+s1.getId()+","+"s2id是"+s2.getId());
    }

    public void changeId2(Student s1,Student s2){
        Student s3=s1;
        s1=s2;
        s2=s3;
        System.out.println("changeId2中的s1id是"+s1.getId()+",s2id是"+s2.getId());
    }
}
class Student{
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

他的执行结果:

changeId2中的s1id是2,s2id是1
main中的s1id是1,s2id是2

我们发现这个在子方法中对象的值是改变了但是main方法中的值还是原先的样子那这样就不符合引用传递了因为他其实并没有改变原先的对象

如果我们以值传递的观点来解释那么就可以说的通了我们传入的两个参数s1、s2在传递过去后会复制一份为s1复制、s2复制然后在子方法中是对这两个复制过后的对象进行的操作执行完之后这些复制的对象就会被回收所以就出现了我们在主方法中看到这两个对象的值是没有改变的

事实上也是如此我们可以同样来解释例子一种为啥传入了对象但是主方法中的值却改变了

我们知道对象这些都是在堆中存储的我们在向方法中传递的实际上是这个对象在堆中的地址我们传递的对象实际上就是传递的对象的地址:

在这里插入图片描述

因为s1与s1复制都是指向的ox123456s1复制改变了值那么s1看到的值也就发生了改变即使是s1复制最后被回收ox123456的改变不会恢复

五、结论

所以Java中的传递只有值传递而没有引用传递只不过传递为基本数据类型的话是复制的数值而对象类型的话则是复制的对象存放地址


相关文章

猜您喜欢

网友评论

Copyright 2020 www.fresh-weather.com 【世纪下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式