值传递和引用传递----java

手把手教你用6轴IMU跑通LIO-SAM:参数配置与代码修改保姆级教程 本文提供了一套完整的6轴IMU适配LIO-SAM的解决方案,包括参数配置与代码修改的详细步骤。从理解6轴与9轴IMU的关键差异入手,逐步指导如何调整核心配置文件params.yaml、重构utility.h关键函数、优化mapOptimization.cpp的位姿融合逻辑,并给出编译验证与性能调优建议,帮助开发者快速实现6轴IMU在LIO-SAM中的稳定运行。 阅读详情

本文章来自于http://hi.baidu.com/xzhilie/blog/item/8bc05c8dbdc86816b21bbae3.html

首先,推荐对Java有一定理解的同仁一本书《Practical Java》。在《Practical Java》中也有一个章节介绍Java中关于传值和传引用的问题,堪称经典。《Practical Java》在Java中,事实上底层工作原理不存在传引用的概念,这也象《Practical Java》中所说的那样,Java中只有传值。这句话理解起来需要费一定的周折。

      熟悉C的程序员都用过指针,对指针可谓爱之深恨之切。指针是指向一块内存地址的内存数据(有些拗口),也就是说指针本身是一个占用4字节内存的int(32 位系统内),而这个int值恰恰又是另一块内存的地址。比如"hello"这个字串,存放在@0x0000F000这个地址到@0x0000F005这段内存区域内(包括0x00的结束字节)。而在@0x0000FFF0到@0x0000FFF03这四个字节内存放着一个int,这个int的值是 @0x0000F000。这样就形成了一个指向"hello"字串的指针。

      在Java中,很多人说没有指针,事实上,在Java更深层次里,到处都是大师封装好的精美绝伦的指针。为了更容易的讲解Java中关于类和类型的调用,Java中出现了值与引用的说法。浅显的来说,我们可以认为Java中的引用与C中的指针等效(其实差别非常非常大,但是为了说明我们今天的问题,把他们理解为等效是没有任何问题的)。

      所谓传引用的说法是为了更好的讲解调用方式。基于上面对指针的理解,我们不难看出,指针其实也是一个int值,所谓传引用,我们是复制了复制了指针的int值进行传递。为了便于理解,我们可以姑且把指针看作一种数据类型,透明化指针的int特性,从而提出传引用的概念。

      重申一遍:Java中只有传值。

      1所谓传值和传引用

      传值和传引用的问题一直是Java里争论的话题。与C++不同的,Java里面没有指针的概念,Java的设计者巧妙的对指针的操作进行了管理。事实上,在懂C++的Java程序员眼中,Java到处都是精美绝伦的指针。
下面举个简单的例子,说明什么是传值,什么是传引用。
//例1
void method1(){
int x=0;
this.change(x);
System.out.println(x);
}

void change(int i){
i=1;
}

      很显然的,在mothod1中执行了change(x)后,x的值并不会因为change方法中将输入参数赋值为1而变成1,也就是说在执行change(x)后,x的值z依然是0。这是因为x传递给change(int i)的是值。这就是最简单的传值。
同样的,进行一点简单的变化。
//例2
void method1(){
StringBuffer x=new StringBuffer("Hello");
this.change(x);
System.out.println(x);
}

void change(StringBuffer i){
i.append(" world!");
}
      看起来没什么变化,但是这次mothed1中执行了change (x)后,x的值不再是"Hello"了,而是变成了"Hello world!"。这是因为x传递给change(i)的是x的引用。这是最经典的传引用。
似乎有些奇怪了,两段程序没有特别的不同,可是为什么一个传的是值而另一个传的是引用呢?......

      2非要搞清楚传值还是传引用的问题吗?

      搞清楚这自然是有必要的,不然我也不需要写这么多了,不过的确没有到"非要"的地步。


      首先,如果我们不太关心什么是传值什么是传引用,我们一样能写出漂亮的代码,但是这些代码在运行过程中可能会存在着极大的隐患。全局变量是让大家深恶痛绝(又难以割舍)的东西,原因就是使用全局变量要特别注意数据的保护。如果在多线程的程序里使用全局变量简直就等于跟自己过不去。不了解传值和传引用的问题,跟使用全局变量不考虑数据保护的罪过是不相上下下的,甚至有时候比它还要糟。你会莫名其妙,为什么我的返回参数没有起作用,为什么我传进去的参数变成了这样......?
一个例子:
//例3
void mothed1(){
int x=0;
int y=1;
switchValue(x,y);
System.out.println("x="+x);
System.out.println("y="+y);
}
void switchValue(int a,int b){

int c=a;
a=b;
b=c;
}
      上面是一个交换a,b值的函数,看起来似乎蛮正确的,但是这个函数永远也不会完成你想要的工作。
      还有一个例子:
//例4
StringBuffer a=new StringBuffer("I am a ");
StringBuffer b=a;
a.append("after append");
a=b;
System.out.println("a="+a);
在编程过程中,经常会遇到这种情况,一个变量的值要被临时改变一下,等用完之后再恢复到开始的值。就好像上面的例子,a为了保持它的值,使用b=a做赋值,之后a被改变,再之后a把暂存在b里面的值取回来。这是我们一厢情愿的想法,而事实上,这段代码执行后,你会发现a的值已经改变了。
以上是两个最简单的例子,真正的程序开发过程中,比这要复杂的情况每天都会遇到。

      3类型和类

      Java 提出的思想,在Java里面任何东西都是类。但是Java里面同时还有简单数据类型int,byte,char,boolean,与这些数据类型相对应的类是Integer,Byte,Character,Boolean,这样做依然不会破坏Java关于任何东西都是类的提法。这里提到数据类型和类似乎和我们要说的传值和传引用的问题无关,但这是我们分辨传值和传引用的基础。

      4试图分辨传值还是传引用

      为什么是"试图分辨"呢?很简单,传值和传引用的问题无处不在,但是似乎还没有人能正统的给出标准,怎样的就是值拷贝调用,怎样的就是引用调用。面对这个问题,我们更多的应该是来自平时积累对Java的理解。
      回过头来,我们分析一下上面的几个例子:
      先看例1,即使你不明白为什么,但是你应该知道这样做肯定不会改变x的值。为了方便说明,我们给例子都加上行号。
//例1
1 void method1(){
2   int x=0;
3   this.change(x);
4 }
5
6 void change(int i){
7 i=7;
8}
      让我们从内存的存储方式看一下x和I之间到底是什么关系。
      在执行到第2行的时候,变量x指向一个存放着int 0的内存地址。

      变量x---->[存放值0]

      执行第3行调用change(x)方法的时候,内存中是这样的情形:x把自己值在内存中复制一份,然后变量i指向这个被复制出来的0。

      变量x---->[存放值0]
                        ↓进行了一次值复制
      变量x---->[存放值0]

      这时候再执行到第7行的时候,变量i的被赋值为7,而这一步的操作已经跟x没有任何关系了。

      变量x---->[存放值0]
             
      变量x---->[存放值7]

      说到这里应该已经理解为什么change(x)不能改变x的值了吧?因为这个例子是传值的。
那么,试着分析一下为什么例三中的switchValue()方法不能完成变量值交换的工作?
再看例2。
//例2
1void method1(){
2 StringBuffer x=new StringBuffer("Hello");
3 this.change(x);
4}
5
6void change(StringBuffer i){
7 i.append(" world!");
8}
      例2似乎和例1从代码上看不出什么差别,但是执行结果却是change(x)能改变x的值。依然才从内存的存储角度来看看例2的蹊跷在哪里。
在执行到第2行时候,同例1一样,x指向一个存放"Hello"的内存空间。

      变量x---->[存放值"Hello"]

      接下来执行第三行change(x),注意,这里就与例1有了本质的不同:调用change(x)时,变量i也指向了x指向的内存空间,而不是指向x的一个拷贝。

      变量x \
              -->[存放值"Hello"]
      变量x /

      于是,第7行对i调用append方法,改变i指向的内存空间的值,x的值也就随之改变了。

      变量x \
              -->[追加为"Hello World!"]
      变量x /

      为什么x值能改变呢?因为这个例子是传引用的。
这几个例子是明白了,可是很多人会开始有另一个疑问了:这样看来,到底什么时候是传的值什么时候是传得引用呢?于是,我们前面讲到的类型和类在这里就派上了用场:对于参数传递,如果是简单数据类型,那么它传递的是值拷贝,对于类的实例它传递的是类的引用。需要注意的是,这条规则只适用于参数传递。为什么这么说呢?我们看看这样一个例子:
//例5
String str="abcdefghijk";
str.replaceAll("b","B");
      这两句执行后,str的内容依然是"abcdefghijk",但是我们明明是对str操作的,为什么是这样的呢?因为str的值究竟会不会被改变完全取决于replaceAll这个方法是怎么实现的。类似的,有这样一个例子:
//例6
1 void method1() {
2 StringBuffer x = new StringBuffer("Hello");
3 change1(x);
4 System.out.println(x);
5 }
6
7 void method2() {
8 StringBuffer x = new StringBuffer("Hello");
9 change2(x);
10 System.out.println(x);
11 }
12
13 void change1(StringBuffer sb) {
14 sb.append(" world!");
15 }
16
17 void change2(StringBuffer sb) {
18 sb = new StringBuffer("hi");
19 sb.append(" world!");
20 }
      调用method1(),屏幕打印结果为:"Hello world!"
调用method2(),我们认为结果应该是"hi world",因为sb传进来的是引用。可是实际执行的结果是"Hello"!
难道change2()又变成传值了?!其实change1()和change2()的确都是通过参数传入引用,但是在方法内部因为处理方法的不同而使结果大相径庭。我们还是从内存的角度分析:
执行method1()和change1()不用再多说了,上面的例子已经讲解过,这里我们分析一下method2()和change2()。
      程序执行到第8行,x指向一个存放着"Hello"的内存空间。

      变量x---->[存放值"Hello"]

      第9行调用change2,将sb指向x指向的内存空间,也就是传入x的引用。

      变量x \
              -->[存放值"Hello"]
      变量x /

      到这里为止还没有什么异样,接下来执行18行,这里就出现了类似传入值拷贝的变化:new 方法并没有改变sb指向内存的内容,而是在内从中开辟了一块新的空间存放串"hi",同时sb指向了这块空间。

      变量x---->[存放值"Hello"]
            ×原有的引用被切断
      变量x---->[另一块存放"hi"的空间]

      接下来再对sb进行append已经和x没有任何关系了。
所以,还有一条不成规则的规则:对于函数调用,最终效果是什么完全看函数内部的实现。比较标准的做法是如果会改变引用的内容,则使用void作为方法返回值,而不会改变引用内容的则在返回值中返回新的值。
虽然已经说了这么多,但是感觉传值还是传引用的问题依然没有完全说清楚。因为这个问题本身就是很难归纳总结的问题,所以更多的理解要靠平时的积累和形成。下面几个例子,给大家尝试进行分析。
//例7,打印结果是什么?
public static void main(String[] args) {
int a;
int b;
StringBuffer c;
StringBuffer d;
a = 0;
b = a;
c = new StringBuffer("This is c");
d = c;

a = 2;
c.append("!!");

System.out.println("a=" + a);
System.out.println("b=" + b);
System.out.println("c=" + c);
System.out.println("d=" + d);
}

//例8,打印结果是什么?
public class Test{

        public static void main(String[] args) {

         StringBuffer sb = new StringBuffer("Hello ");

         System.out.println("Before change, sb = " + sb);

         changeData(sb);

         System.out.println("After changeData(n), sb = " + sb);

     }

     

        public static void changeData(StringBuffer strBuf) {

            StringBuffer sb2 = new StringBuffer("Hi ");

            strBuf = sb2;

            sb2.append("World!");

     }

}

YOLOv11训练命令完全指南:从核心参数解析到高级调优实战(数据配置、epochs设定、batch-size优化与img-size调整)(二) 本文介绍了YOLOv11训练命令的完整配置与解析,提供了基础训练命令示例及参数详解。示例命令包含数据集配置(coco.yaml)、训练轮次(300)、批次大小(64)、图像尺寸(640)等核心参数,以及优化器(AdamW)、学习率(0.001)等调优选项。通过代码实现展示了训练器的初始化流程,包括参数解析、设备设置、数据加载和模型创建等关键步骤,为YOLOv11模型训练提供了实用指导。 阅读详情

相关推荐

Abaqus中Cohesive单元建模:从本构到失效的完整指南

本文提供了Abaqus中Cohesive单元建模的完整指南,涵盖从本构模型到失效分析的全过程。详细解析了Cohesive单元作为模拟界面粘结与失效的关键工具,其核心在于弹性本构、损伤起始准则和损伤演化定律的设置。文章通过双悬臂梁(DCB)实例,手把手指导前处理、材料定义、求解设置及后处理分析,并分享了刚度、强度、断裂能等关键参数的影响与收敛性调优的实用避坑技巧,帮助用户准确模拟复合材料及胶接结构的界面失效行为。

cuda7parallel的博客 700

什么是Java值传递和引用传递?

什么是Java值传递和引用传递?

java1234的博客 949

AI工作流革命:从n8n到Sora2,揭秘自动化视频创作的底层逻辑

本文深入探讨了AI工作流在自动化视频创作中的应用,重点介绍了n8n、Coze和Sora2的组合如何实现从链接输入到视频输出的全流程自动化。通过三层架构解析、关键技术模块优化及成本控制策略,这套方案显著提升了视频生产效率,适用于电商、热点追踪等多种场景。

gg901的博客 1082

10.java的值传递和引用传递

Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用。

m0_73798489的博客 2008

R语言笔记三:矩阵、数组、列表和数据框

1.矩阵        矩阵是二维的,需要有行和列。向量是一维的。        在R软件中,矩阵是有维数的向量,这里的矩阵元素可以是数值型、字符型或者逻辑型,但是每个元素必须拥有相同的模式,这个和向量一致。 (1)创建矩阵: m <- matrix(1:20,4,5) 行数和列数的分配必须满足分配条件。若分配的行列过大,分配的元素不足够,则报错。 m <-

weixin_44384631的博客 6210

基于Matlab与Gurobi的园区微电网风光储协同规划:从独立运营到联合优化的建模实战

本文详细介绍了如何利用Matlab与Gurobi进行园区微电网的风光储协同规划建模实战。通过构建从独立运营到联合优化的数学模型,结合Yalmip工具箱,旨在解决源荷不匹配问题,实现储能系统的最优配置与运行,从而降低总供电成本并提升新能源利用率。

weixin_29053073的博客 140

java引用传递和值传递的详细探讨

问题来源于一道广泛的面试题:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 为了解决这个问题,查阅了各种资料,却发现没有统一的结果,因此只能从我自己的角度给出一个答案。欢迎大家探讨这个问题。

独恋幽兰的专栏 2万+

Matlab 普通kriging(克里金)插值

Matlab 普通kriging(克里金)插值

dayuhaitang1的博客 4570

java中的值传递和引用传递

值传递(Pass By Value或者Call By Value)是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。一般java中的基础类型数据传递都是值传递。 引用传递(Pass By Reference或者Call By Reference)一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。一般java中实例(包装)对象的传递是引用传递。 一、基本类型和引用类型在内存中的不同之处 int num = 10; String str = "hello"

m0_51660523的博客 4680

Archery通过OpenResty代理转发后登录一直提示Forbidden

测试几遍,连账号密码都没用验证,因为不管输什么都是提示Forbidden。找到配置文件settings.py,下面命令可到配置文件路径。回到页面刷新,随便输入个账号密码,验证失败证明请求成功了。查看Preview,提示CSRF验证失败,请求被中断。域名:dba.hkeasyspeed.com。打开开发者工具查看,网络里面可以看到报403。添加一条配置,把你配置域名添加进去。可以看到页面可以正常访问到。进入Archery容器。重启Archery容器。正常输入账号密码,OK。

万物皆可学 3143

从一只龙虾到一支团队:OpenClaw 单 Bot 多 Agent 配置实践

单 Bot 多 Agent只有一个对外的聊天入口(飞书 Bot)内部有多个独立的 AI Agent,各司其职主 Agent(总指挥)负责接收任务并分配给子 Agent子 Agent 完成任务后将结果返回给主 Agent角色Agent ID职责使用场景🎯 总指挥main-agent统筹协调,任务分发接收所有用户请求✍️ 笔杆子内容创作公众号、博客、小红书🔬 参谋canmou深度研究竞品分析、市场调研📋 运营官operations运营管理邮件、日历、社交媒体。

Maynor的博客 1080

java的值传递和引用传递

一、基本类型和引用类型的理解 Java中的数据类型分为两种为基本类型和引用类型。 1、基本类型的变量保存原始值,所以变量就是数据本身。 常见的基本类型:byte,short,int,long,char,float,double,Boolean,returnAddress。 2、引用类型的变量保存引用值,所谓的引用值就是对象所在内存空间的“首地址值”,通过对这个引用值来操作对象。 常见的引用类型:类类型,接口类型和数组。 二、值传递和引用传递的理解 1、值传递 在方法...

cai13070139328的博客 2372

3.摄像头组件- CVP (ISP)

本文介绍 车载摄像头组件-ISP

2401_83458819的博客 1617

Java 的值传递和引用传递

Java 的值传递和引用传递

ChineseSoftware的博客 2532

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Java中的值传递和引用传递

Java不管是基本类型还是引用类型,参数传递的方式只有一种:值传递而有两种表现:值传递和引用传递,是因为对象的属性不同。

2301_81453175的博客 1018

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Java中的值传递和引用传递详解

Java中的值传递和引用传递详解

寂夜了无痕的博客 1326

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Java值传递和引用传递的区别

原文 前景 关于这个问题,引发过很多广泛的讨论,看来很多程序员对于这个问题的理解都不尽相同,甚至很多人理解的是错误的。还有的人可能知道Java中的参数传递是值传递,但是说不出来为什么。 在开始深入讲解之前,有必要纠正一下大家以前的那些错误看法了。如果你有以下想法,那么你有必要好好阅读本文。 错误理解一:值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递。如果是个引用,就是引用传递。 错误理解二: Java是引用传递。 错误理解三:传递的参数如果是普通类型,那就是值传递,如果是对象,那就是引用

ss810540895的博客 850

Java值传递和引用传递

目录 一、Java的数据类型 二、值传递 1、定义 2、代码展示 3、画图展示 4、String类型属于值传递 三、引用传递 1、定义 2、代码展示 3、总结 一、Java的数据类型 我们要了解java的值传递和引用传递那么我们必须先引出java的数据类型,那我们接下来说说java的数据类型包括什么? java的数据类型分为两大类:基本数据类型和引用数据类型 基本数据类型: 4种整数类型:byte、short、int、long 2种浮点数类型:float、doubl..

qq_48241564的博客 1548

Java里边什么是值传递和引用传递?两个有什么区别

学过java基础的人都知道,在java中参数的传递过程中有值传递和应用传递,那么这两个到底有什么区别呢,下面我通过例子为大家详细的介绍下。 我们都知道Java中有八种数据类型,基础数据类型分别是:byte,short,int,long,float,double,char,boolean,引用数据类型分别是:数组,类和接口。方法传参的时候我们有两种,一种是形式参数(定义方法时写的参数),一种是实际...

坐看云起时_雨宣 8345

【Java】值传递和引用传递

基本类型和引用类型 基本类型变量存储着变量的值。 引用类型变量存储的是对象的地址,地址指向堆中引用的对象。 int num=10; String str="abc"; 基本类型使用“=”赋值,改变变量的值。 引用类型使用“=”赋值,改变变量的指向。 num=20; str="cba"; 此时,"abc"再无引用变量指向,成了垃圾,会在JVM GC的时候释放掉。 实际参数...

csdn_inside的博客 422

对于Java的值传递和引用传递的区别

我知道有人会说,Java只有值传递而没有引用传递,但是如果把引用地址也看成一个值的话,是可以这么说的。 对于两个传递的定义是什么呢? 第一,值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。(一般发生在基本数据类型当中) 第二,引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。 所以对该副本进行操作时,会同时改变原对象。(发生在引

子杰小同学的博客 4137

c语言值传递和引用传递的区别_Java是值传递还是引用传递

Java 到底是值传递还是引用传递?先说结论,Java 都是值传递,不存在引用传递。数据类型首先从 Java 数据类型入手,Java 的数据类型分为基础类型和引用类型。基础类型声明时在栈空间开辟内存,数值直接存储在栈空间。引用类型声明时在栈上开辟内存,用于存储对象的地址,而对象的具体信息存储在堆空间。int num = 10;String str = "java";如图,num 是基本类...

weixin_39586825的博客 631

java list引用传递_java的值传递和引用传递

昨天博主在对于值传递和引用传递这里栽了一个大坑啊,导致一下午时间都浪费在这里,我们先说下值传递和引用传递java官方解释:值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响实际参数的值。引用传递:(形式参数类型是引用数据类型参数):也称为传地址。方法...

weixin_39530509的博客 2638

Java 值传递和引用传递

值传递:在调用函数的时候,将实际参数复制一份传递到函数中,这样在函数中对参数进行修改的 时候,就不会影响到原来的实际参数 引用传递:在调用函数的时候,将实际参数的地址直接传递函数中,这样在函数中对参数进行修改 的时候,就会影响到实际参数 值传递 引用传递 根本区别 会创建一个副本(copy) 不创建副本 结果 函数中无法改变原来的对象 函数可以改变原来的对象 将对象创建.

Hello_qjh的博客 3355

java值传递和引用传递

因此可见:在Java中所有的参数传递,不管基本类型还是引用类型,都是值传递,或者说是副本传递。如果是对基本数据类型的数据进行操作,由于原始内容和副本都是存储实际值,并且是在不同的栈区,因此形参的操作,不影响原始内容。如果是对引用类型的数据进行操作,分两种情况,一种是形参和实参保持指向同一个对象地址,则形参的操作,会影响实参指向的对象的内容。一种是形参被改动指向新的对象地址(如重新赋值引用),则形参的操作,不会影响实参指向的对象的内容。

u013072811的博客 433
上一篇: java---名词术语
下一篇: System.getProperty解读
dplhere
博客等级 码龄14年 0粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值