前言

这是一篇很基础的文章,有一天我突然想到Java中只有值传递,但是为什么在传递对象的时候,里面的值修改后,实参也会被修改,我就特意去了解了一下这些相关的知识。这一学,我发现我之前的一些了解是错误的,不只是是对Java传递参数理解有问题,对C++中这传递也是有问题的。因此我觉得我应该特地写一篇随笔,帮我理解,毕竟感觉真正的弄懂,是能够帮助别人理解。

正文

值传递

简单的基本类型

关于值传递基本类型我就不过多叙述了,感觉有点像水字数一样。

就简单举个例子过一下

public class Main {
public static void change(int a){
a = 2;
}
public static void main(String[] args) {
int a = 1;
change(a);
System.out.println(a);
}
}

运行截图:

基本的数据类型都是这样的情况

传递引用类型

接下来来传递引用类型

现在说一下前言中说我在C++关于传递的错误理解

我一直以为,C++中的引用传递,传递的参数与实参指向同一个对象(这是对的),因此传递过去实际是实参的地址,后面我才发现我理解错了,实际形参就直接理解为就是实参的一个别名。

接下来说说我另一个理解错误的地方(这部分结合值传递引用类型讲解)

我过去的理解,值传递是不可能能够改变实参的,在Java中,我又发现好像可以改变耶,我就以为是不是我记错了,Java中的传递方式也是有两种,除了值传递,还有引用传递,我还以为我记错了,我特意上网查了一下,确实没有,我也特意弄懂了这一部分。

下面我将通过例子进行讲解

class Student {
public int id;
public String name; public Student(int id, String name) {
this.id = id;
this.name = name;
} @Override
public String toString() {
return "Student{id=" + id + ", name='" + name + "'}";
}
} public class Main {
public static void change1(Student student) {
student.id = 2;
} public static void change2(Student student) {
student=new Student(2,"Bob");
} public static void main(String[] args) {
Student student1 = new Student(1, "Alice");
Student student2 = new Student(1, "Alice");
System.out.println("student1改变前 " + student1);
System.out.println("student2改变前 " + student2);
change1(student1);
change2(student2);
System.out.println("根据change1方法改变后 " + student1);
System.out.println("根据change2方法改变后 " + student2);
}
}

在例子中我们定义了Student类用充当引用对象,方法change1相当于setter方法,改变形参对象内属性值;方法change2则是使更换指向对象。

运行截图:

最后方法change1根据使得实参对象内属性值发生改变,而方法change2却没用使得实参更换指向对象。

原因讲解:

change1(student1)

形参 student1 得到 假设地址为0xAAA 的拷贝。

student.id = 2; 是通过这份拷贝里的地址找到原对象,把 id 改成 2。

原对象确实被改了,因此 student1 打印出 Student{id=2, name='Alice'}。

change2(student2)

形参 student2 得到 假设地址为0xBBB 的拷贝。(因为是new Student()创建,执行两个完全独立的对象)

student = new Student(2,"Bob"); 只是 把这份拷贝里的地址改成了新对象 0xCCC,原来的 student2 仍指向 0xBBB,毫无变化。

所以 student2 打印依旧是 Student{id=1, name='Alice'}。

对应值传递引用对象,更换指向对象,例子很多,里面有很多很隐晦的,如对String赋值,由于String是不可变,用final修饰,看向在实现String更换值了,实际是更换了指向对象;还有Integer的自动装箱,这些例子我参考了一下这篇文章(https://blog.csdn.net/yiridancan/article/details/149813906)

结论

  • Java 中进行值传递,方法收到的永远是实参的一份拷贝,也可以说是副本,在传递基本类型时,是传递真正的数,对这份拷贝本身做任何重新赋值都不会影响原来的变量;在传递引用类型时,是传递的是对象地址的副本,而但通过拷贝里保存的对象地址去改对象内部字段是可以的。*

面试常考基础,Java传递方式--值传递的更多相关文章

  1. 面试常考知识点——Java(JVM,JDK,JRE)

    1. 什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? 答:(1)Java虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Java虚拟机执行的字节码文件. ...

  2. java面试3-对于java中值传递的理解(Hollis)

    这是根据Hollis的直面java内容习得(有兴趣的可以加他微信公众号) 对于初学者来说,要理解java中的值传递很难理解,为什么说java只有值传递?那引用传递呢? java中的错误理解: 错误理解 ...

  3. PHP面试常考内容之Memcache和Redis(2)

    你好,是我琉忆.继周一(2019.2-18)发布的"PHP面试常考内容之Memcache和Redis(1)"后,这是第二篇,感谢你的支持和阅读.本周(2019.2-18至2-22) ...

  4. Java是值传递还是引用传递?

    Java的值传递和引用传递在面试中一般都会都被涉及到,今天我们就来聊聊这个问题.这个问题一般是相对函数而言的,也就是Java中所说的方法参数,那么我们先来回顾一下在程序设计语言中有关参数传递给方法的两 ...

  5. 堆栈详解 + 彻底理解Java的值传递和引用传递

    本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ...

  6. Java的值传递和引用传递的说法

    学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨论的话题又是充满争议:有的论坛帖子说Java ...

  7. PHP面试常考内容之面向对象(2)

    PHP面试专栏正式起更,每周一.三.五更新,提供最好最优质的PHP面试内容.继上一篇"PHP面试常考内容之面向对象(1)"发表后,今天更新(2),需要(1)的可以直接点击文字进行跳 ...

  8. Does Java pass by reference or pass by value?(Java是值传递还是引用传递) - 总结

    这个话题一直是Java程序员的一个热议话题,争论不断,但是不论是你百度搜也好还是去看官方的文档中所标明的也好,得到的都只有一个结论:Java只有值传递. 在这里就不贴代码细致解释了,让我们来看看一些论 ...

  9. 前端面试常考知识点---CSS

    前端面试常考知识点---js 1.CSS3的新特性有哪些 点我查看 CSS3选择器 . CSS3边框与圆角 CSS3圆角border-radius:属性值由两个参数值构成: value1 / valu ...

  10. 数据存储在哪里? Java是值传递还是引用传递?

    寄存器 : 最快的存储区,位于处理器中,寄存器会按需求自行分配空间,java不能控制寄存器,所以在程序中感觉不到它的存在 栈(stack) : 位于RAM(内存)中,速度仅次于寄存器,存储对象的引用( ...

随机推荐

  1. 全球首个无限执行的 AI 出现!给我玩爽了

    给 AI 一句话,它就能自主执行任务,生成复杂的大型网站.几十页的 PPT.万字爆款图文.千万字长篇小说? 据说这是世界上第一款无限的 AI 智能体 -- Flowith. 无限这个词听起来有点东西啊 ...

  2. python C3算法

    Python MRO C3算法是python当中计算类继承顺序的一个算法,从python2.3以后就一直使用此算法了. c3 linearization算法称为c3线性化算法 C3算法原理 首先定义几 ...

  3. 华为MAAS、阿里云PAI、亚马逊AWS SageMaker、微软Azure ML各大模型深度分析对比

    一.技术架构深度对比 1. 硬件基础设施 平台 自研芯片 分布式训练方案 边缘协同能力 华为MAAS 昇腾Ascend 910 + Atlas 900集群 MindSpore + HCCL(华为集合通 ...

  4. Java实现密码、文件MD5加密,密码sha256、sha384、sha512Hex等加密

    SHA512加密(参考:https://blog.csdn.net/zdj_Develop/article/details/89326621?utm_medium=distribute.pc_rele ...

  5. 鸿蒙运动项目开发:封装超级好用的 RCP 网络库(中)—— 错误处理,会话管理与网络状态检测篇

    鸿蒙核心技术##运动开发## Remote Communication Kit(远场通信服务) 在上篇中,我们介绍了 RCP 网络库的核心功能,包括请求参数的封装.响应内容的转换以及拦截器与日志记录机 ...

  6. laravel-casbin-admin

    基于 vue-element-admin laraveljwtcasbin 整合的前后端分离的rbac权限管理系统 功能和介绍 github地址 系统采用前后端分离架构,是一个企业后台解决方案. 前端 ...

  7. vue3使用composables来取代mixins 来状态复用

    前言 最简单理解composables的方式 就是将其视为vue版的自定义hooks 来个demo 比如 页面初始化的时候 我需要请求接口 获取数据 并回填至表单 以前的做法 src/pages/in ...

  8. 前端开发系列059-网络篇之网络基础知识和HTTP协议

    一.网络编程基本概念 1.1 客户端和服务器的基本概念 客户端(Client)能从服务器获取资源为客户提供服务的程序(设备). 服务器(Server)为客户端提供服务.提供数据.提供资源的机器. 说明 ...

  9. Day3 备战CCF-CSP练习

    Day3 题目描述 目前在一个很大的平面房间里有 \(n\) 个无线路由器,每个无线路由器都固定在某个点上. 任何两个无线路由器只要距离不超过 \(r\) 就能互相建立网络连接. 除此以外,另有 \( ...

  10. PID算法及其优化

    PID算法及其优化 1. 经典PID公式 位置式PID公式 增量式PID公式 PID适用范围: 线性时不变低阶(二阶及以下)控制系统,当然可以通过一些优化来一定程度上解决非线性和将高阶系统简化至二阶以 ...