Java是值传递还是引用传递

根据我个人的理解,我认为:Java是值传递。

值传递是指在调用方法时将实际参数拷贝一份传递到方法中,这样在方法中如果对参数进行修改,将不会影响到实际参数。

  ① 当传的是基本类型时,传的是值的拷贝,对拷贝变量的修改不影响原变量;

  ② 当传的是的引用类型时,传的是引用地址的拷贝,但是拷贝的地址和真实地址指向的都是同一个真实数据,因此可以修改原变量中的值。

首先来解释一下什么是引用传递,什么是值传递。

  • 引用传递(pass by reference)是指在调用方法时将实际参数的地址直接传递到方法中,那么在方法中对参数所进行的修改,将影响到实际参数。

  • 值传递(pass by value)是指在调用方法时将实际参数拷贝一份传递到方法中,这样在方法中如果对参数进行修改,将不会影响到实际参数。

我们先来看一个简单的例子:

public void test(){
    int a = 1;
    alter();
    System.out.println(a);
}

private void alter(int a){
    a = a + 1;
}
// 输出:a的值为1

以上代码在test()方法中定义了一个基本类型的变量a,然后调用alter()方法试图改变这个变量,最后输出的还是原来的值。

首先我们要清楚,一个方法中的局部变量是存在栈中的,

  ① 如果是基本类型的变量则直接存的是这个变量的值;

  ② 如果是引用类型的变量则存的是值的引用地址,指向堆中具体的对象。

上面的例子中,调用alter()方法传递的a,其实是a变量的拷贝,不是真正的a,在alter()方法中改变的是拷贝,对真正的a是没有影响的。

但是,对于引用类型来讲,还会是这样吗?

pubilc void test(){
    User user = new User();
    user.setAge(23);
    alter(user); // 这里传入的是存放于栈中的User的引用地址
    System.out.println("年龄" + user.getAge());
}

private void alter(User user){
    user.setAge(24);
}

// 输出:年龄 24

这里却发现该用户的年龄被修改了,原因是当调用alter()方法传入变量时,也是拷贝变量,但是这里的拷贝只是栈中的引用地址,并不会拷贝堆中的数据,虽然变量是拷贝,但是指向的地址是同一个,因此对变量中的数据修改时,还是会影响到原来真实的变量,但是,如果我们修改的是变量在栈中的地址,则不会影响原变量,例如下面这段代码:

public void test(){
    User user = new User();
    user.setAge(18);
    alter(user);
    System.out.println("年龄" + user.getAge());
}

private void alter(User user){
    user = new User(); // 这里又创建了一个新的User类型的对象,并给形参user赋予了一个新的引用地址
    user.setAge(19); // 修改的不再是传进来的那个user了,而是新的user的年龄
}

// 输出:年龄 18

这种是修改变量在栈中的地址,则不会影响原变量。

但是要注意当传入的是不可变的引用类型时,如String,它的底层的数组引用变量是使用final进行修饰了的,所以引用地址是无法改变的,故无法修改原变量的值。

本文转载于网络 如有侵权请联系删除

相关文章

  • Java中synchronized与ReentrantLock性能对比

    前两天逛博客的时候看到有个人写了一篇博客说ReentrantLock比synchronized慢,这就很违反我的认知了,详细看了他的博客和测试代码,发现了他测试的不严谨,并在评论中友好地指出了他的问题,结果他直接把博客给删了删了了……很多老一辈的程序猿对有synchronized有个性能差的刻板印象,然后极力推崇使用java.util.concurrent包中的lock类,如果你追问他们synchronized和lock实现性能差多少,估计没几个人能答出来。说到这你是不是也很想知道我的测试结果?synchronized与ReentrantLock所实现的功能差不多,用途也大幅度重合,索性我们就来测测这二者的性能差异。实测结果测试平台:jdk11,MacBookPro(13-inch,2017),jmh测试 测试代码如下: publicclassLockTest{privatestaticObjectlock=newObject(); privatestaticReentrantLockreentrantLock=newReentrantLock(); privatestaticlon

  • 反编译所有图片加载库,让OOM无所遁形!

    作者:ZhouZhengyi链接:https://juejin.im/post/5ea1c46851882573a25f3ec31.背景 最近看滴滴开源的Dokit框架中有一个大图监控的功能,可以对图片的文件大小和所占用的内存大小设置一个阈值,当图片超过该值的时候进行提示。这个功能对于我们在做APK体积压缩,内存管理的时候还是很有用的,比如当我们要从后台返回的连接中加载一张图片,这张图片的大小我们是不知道的,虽然现在大家都使用Glide等三方图片加载框架,框架会自动对图片进行压缩,但是依然会出现压缩后所占内存超过预期的情况。这时候我们可以在开发、测试和预生产阶段使用大图监控来识别出那些超标的图片。 2.需求在讨论如何做之前,我们必须明确我们要做什么。该大图监控框架我觉得应该实现以下功能:能对图片的文件大小和所占用的内存大小设置阈值,超过其中之一则报警。能够得到超标图片的详细信息,包括当前文件大小,所占用内存,图片分辨率,图片的略缩图,图片的加载地址,view的尺寸。能够通过弹窗或者列表的方式查看当前超标的图片信息。不论是本地加载图片还是网络加载图片都能够进行监控。3.实现思路 要实现对

  • 聊聊skywalking的RemoteClientManager

    序本文主要研究一下skywalking的RemoteClientManagerRemoteClientManagerskywalking-6.6.0/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/remote/client/RemoteClientManager.javapublicclassRemoteClientManagerimplementsService{ ​ privatestaticfinalLoggerlogger=LoggerFactory.getLogger(RemoteClientManager.class); ​ privatefinalModuleDefineHoldermoduleDefineHolder; privateClusterNodesQueryclusterNodesQuery; privatevolatileList<RemoteClient>usingClients; privateGaugeMetricsgauge; priv

  • 三分钟迁移 antd@4

    文章作者:陈帅等13w人 文章来源:https://zhuanlan.zhihu.com/p/109067115antd@4rc发布已经有一段时间了(大概已经两周了),官网[1]也已同步放出。最为一个酷爱尝鲜的人,当然要第一时间安装升级。在咨询了豆酱老师得到了api不会修改的承诺之后,我已经在自己的项目中迁移完成。第一时间享受到了的antd@4各种优势。?升级点首先对我而言最大的改进在于性能,select,table和tree已经全面支持了虚拟滚动,作为了早早的使用了rc-tree来解决性能问题的人,antd@4中提供自然是更好不过了,毕竟自己写样式和动态是非常复杂的。重写的table和from解决很多遗留的疑难杂症,具体可以查看豆酱老师的antd@4系列文章[2],里面详细写了心路历程,在form中我们不需要使用getFieldDecorator和Form.create这两个方法。已Pro全区块为例,这两个方法分别出现了87和22次,在我自己的一个维护项目中找到了142个getFieldDecorator,更不用说为了封装组件getFieldDecorator被当成props传来传去

  • 设计模式之迭代器与组合模式(三)

    现在我们已经能愉快地看着一页一页罗列出来的菜单进行点菜了。现在又有的小伙伴希望能够加上一份餐后甜点的“子菜单”。怎么办呢?我们不仅仅要支持多个菜单,甚至还要支持菜单中的菜单。如果我们能让甜点菜单变成餐厅菜单集合的一个元素,那该有多好。但是根据现在的实现,根本做不到呀。我们想要的是这样的:我们需要什么现在我们遇到的现实问题是,我们的系统已经达到了一个复杂的级别,如果现在不重新设计,就无法容纳未来增加的菜单或子菜单等需求。所以,在我们的新设计中,真正需要些什么呢?我们需要某种树形结构,可以容纳菜单、子菜单和菜单项我们需要确定能够在每个菜单的各个项之间游走,而且至少要像现在用迭代器一样方便我们也需要能够更有弹性地在菜单项之间游走。比方说,可能只需要遍历甜点菜单,或者可以遍历餐厅的整个菜单(包括甜点菜单在内)。定义组合模式没错,我们要介绍另一个模式解决这个难题。我们并没有放弃迭代器--它仍然是我们解决方案中的一部分--然而,管理菜单的问题已经到了一个迭代器无法解决的新维度。所以,我们将倒退几步,改用组合模式来实现。组合模式:允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以

  • Android开发:详解Handler的内存泄露

    前言内存泄露在Android开发中非常常见 内存泄露的定义:本该被回收的对象不能被回收而停留在堆内存中内存泄露出现的原因:当一个对象已经不再被使用时,本该被回收但却因为有另外一个正在使用的对象持有它的引用从而导致它不能被回收。 这就导致了内存泄漏。本文将详细讲解内存泄露的其中一种情况:在Handler中发生的内存泄露 阅读本文前建议先阅读Android开发:Handler异步通信机制全面解析(包含Looper、MessageQueue) 目录1.背景我们先来看下日常Handler的一般用法:publicclassMainActivityextendsAppCompatActivity{ @Override protectedvoidonCreate(BundlesavedInstanceState){ //主线程创建时便自动创建Looper和对应的MessageQueue,之前执行Loop()进入消息循环 super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //实例化Handler

  • 一个util带你解决动态申请权限问题(2018.8重编版)

    前言Android从API23开始,也就是Android6.0起,有了一个动态申请权限的概念.这里就分享给大家一个util来解决这个问题.不过在代码之前我还有些要说的: 动态申请权限第一次安装应用进入之后会要权限.一般来说,这个要权限都会在广告页之后,进主页面之前,因为如果不在进入之前拿到权限,肯定有些功能就跑不动了,仔细看图片后面的界面,只显示了根路径,下面为空.那再给一张点击了allow重进的图片: 拿到权限后使用直接上代码: publicclassPermissionsUtil{ //读写权限 privatestaticfinalintREQUEST_EXTERNAL_STORAGE=1; privatestaticString[]PERMISSIONS_STORAGE={ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; /** *检查应用程序是否有权写入设备存储 *如果应用程序没有权限,则会提示用户授予权限 * *@paramactivity所在的A

  • java学习之stringbuffer练习2,反转

    java学习之stringbuffer练习2,反转案例演示:案例演示 需求:把字符串反转 举例:键盘录入”abc”输出结果:”cba” 用StringBuffer的功能实现packagecom.ifenx8.study; importjava.util.Scanner; publicclassDemo_4{ /** 案例演示 * 需求:把字符串反转 举例:键盘录入"abc" 输出结果:"cba" 用StringBuffer的功能实现 */ publicstaticvoidmain(String[]args){ Scannersc=newScanner(System.in); System.out.println("请输入一个字符串"); Strings=sc.nextLine(); Strings1=revString(s); System.out.println(s1); } publicstaticStringrevString(Stringline)

  • 2022-02-23:flutter weekly第7期

    flutterweekly是一份免费的每周咨询,可帮助你在Flutter开发方面保持领先地位。每周分享全球精彩文章、教程、插件和视频,如果您觉得有用,请不要吝啬您的掌声、评论、赞赏或任何其他您想给予的认可。如果你有任何关于Flutter或Dart的消息想要与我分享,请联系我。教程CreateyourChromeExtensionusingFlutter(https://medium.com/flutter-students-club/create-your-chrome-extension-using-flutter-79712ffcb439)。如何用flutter开发一个chrome插件,看这个教程就够了。CustomshapedAppBarasseeninthe“BunnySearch”app.(https://medium.com/@daria.orlova/custom-shaped-appbar-as-seen-in-the-bunny-search-app-6312d067485c)该文章展示了如何创建一个自定义形状的AppBar,教程里对自定义形状和动画实现都有详细的解释

  • LINQ之路14:LINQ Operators之排序和分组(Ordering and Grouping)

    本篇继续LINQOperators的介绍,这里要讨论的是LINQ中的排序和分组功能。LINQ的排序操作符有:OrderBy,OrderByDescending,ThenBy,和ThenByDescending,他们返回inputsequence的排序版本。分组操作符GroupBy把一个平展的输入sequence进行分组存放到输出sequence中。 排序/Ordering IEnumerable<TSource>→IOrderedEnumerable<TSource> Operator 说明 SQL语义 OrderBy,ThenBy 对一个sequence按升序排序 ORDERBY... OrderByDescending,ThenByDescending 对一个sequence按降序排序 ORDER BY...DESC Reverse 按倒序返回一个sequence Exceptionthrown 排序操作符以不同顺序返回相同的elements。 OrderBy,OrderByD

  • H3C 802.11n的频宽模式

     

  • 面向对象

    一.python面向对象之__slots__ 1.为对象和实例添加属性/方法: python是一种动态编程语言,可以动态为类和实例添加属性. 定义类: classDog: pass复制 定义一个方法: defget_name(self): returnself.__name复制 给类动态添加属性和方法: Dog.__name='tiger' Dog.get_name=get_name 复制    #调用 dog=Dog() print(dog.get_name()) 复制    输出:tiger   给实例添加属性和方法: fromtypesimportMethodType dog=Dog() dog.__name='tiger' dog.get_name=MethodType(get_name,dog) print(dog.get_name()) 复制    输出: tiger   2.如果要限制添加的属性怎么办?使用__slots__ 示例: classDog: __slots__=('get_name','name') defget_

  • 【题解】Luogu P2889 [USACO07NOV]挤奶的时间Milking Time

    LuoguP2889[USACO07NOV]挤奶的时间MilkingTime 题目描述 传送门Bessieissuchahard-workingcow.Infact,sheissofocusedonmaximizingherproductivitythatshedecidestoschedulehernextN(1≤N≤1,000,000)hours(convenientlylabeled0..N-1)sothatsheproducesasmuchmilkaspossible. FarmerJohnhasalistofM(1≤M≤1,000)possiblyoverlappingintervalsinwhichheisavailableformilking.Eachintervalihasastartinghour(0≤starting_houri≤N),anendinghour(starting_houri<ending_houri≤N),andacorrespondingefficiency(1≤efficiencyi≤1,000,000)whichindicateshowm

  • 关于js解析的一点小问题

    先来看一下下面的一段代码有什么问题? <html><head><scriptsrc="./jquery.min.js"></script> </head><body><divid="test"></div><script>varstr='<scriptsrc="./test.js"></script>';$("#test").append(str); </script> </body></html>     在谷歌(v53)和ff(v48)中都在varstr....这一句报错了。 为毛?因为<script>和str定义中包住的script匹配了,没想到你是这样的匹配。 再深入下去就是浏览器内核的解释问题了。所以暂时打住。 如果把这个script放到其他js文件中引用则不会有问题(这不废话吗)。。。 或者做一下转义: varstr='<scriptsrc="./test.js">

  • 推荐一款接口文档生成工具,apipost,好用

    既能向postman一样调试接口也能生成接口文档,好用 官网:https://docs.apipost.cn/

  • Python调用OpenCV读写视频

    最近因为经常对视频进行操作,所以记录下Python用opencv来读写视频的方法。 一、opencv读视频 python调用opencv来读视频比较简单,可以直接调用cv2.VideoCapture来读取视频和摄像头,基本上,常见的avi和mp4都能够正常读取。cv2.VideoCapture是通过传入数字来读取对应的摄像头,或者通过传入一个路径字符串来读取对应的视频文件。 最简单直接的读取视频的例子如下: importcv2 cap=cv2.VideoCapture(0)#读取摄像头 #cap=cv2.VideoCapture("video.mp4")#读取视频文件 while(True): ret,frame=cap.read() ifret: cv2.imshow("frame",frame) ifcv2.waitKey(1)&0xFF==ord('q'): break else: break cap.release()复制 读取视频后,OpenCV提供了很多的视频相关的属性,我觉得常见且比较有用的几个属性见如下表格(完整表格见官网文档): C/C++:C

  • BZOJ 2115:Xor(线性基+DFS)

    题目链接 题意 中文题意 思路 因为存在环和重边,边来回走是没有意义的,因此最终的答案应该是一条从1到n的路径权值异或上若干个环的权值,那么难点在于如何选取这些环的权值使得最终的答案更优。 使用到线性基的贪心算法来计算。DFS处理出环的异或值,然后将这些值加入到线性基中,贪心选取。 参考 #include<bits/stdc++.h> usingnamespacestd; typedeflonglongLL; typedefpair<int,int>pii; constintINF=0x3f3f3f3f; constintN=5e4+11; structEdge{ intv,nxt; LLw; }edge[N*4]; intn,m,head[N],vis[N],cnt,tot; LLp[70],ans,cir[N*4],dis[N]; voidAdd(intu,intv,LLw){ edge[tot]=(Edge){v,head[u],w};head[u]=tot++; edge[tot]=(Edge){u,head[v],w};head[v]=tot

  • poj 2888 Magic Bracelet &lt;polya定理&gt;

    题目:http://poj.org/problem?id=2888 题意:给定n(n<=10^9)颗珠子,组成一串项链,每颗珠子可以用m种颜色中一种来涂色,如果两种涂色方法通过旋转项链可以得到视为等价。    然后再给定K组限制,每组限制a、b代表颜色a和颜色b不能涂在相邻的珠子上面。问一共有多少种涂色方法。 思路:如果这题没有后面的限制,就和poj2154一样了:http://www.cnblogs.com/jian1573/p/3234627.html   现在我们要处理的就是K种限制,可以用DP求解。i为珠子编号,c为颜色编号那么:dp[i][c]=∑dp[i-1][cc] cc为可以与c相邻的颜色编号;   由于N为1e9O(N)会TLE,所以我们可以用矩阵快速幂来优化为O(lgN):具体用m[i][j]=1,表示合法,m[i][j]=0表示不合法,   那么m^k后的对角线上的元素和即为所求。 1#include<iostream> 2#include<cmath> 3#include<cstdio> 4#include

  • Netezza External Tables --How to use local files in external table

    FROM:http://tennysusantobi.blogspot.com/2012/08/netezza-external-tables.html NetezzaExternalTables   YoucanuseNetezza'sexternaltabletoviewdatafromanexternalfile anduseitlikeadatabasetable.Whenyoucreateanexternaltable,the actualdatastillsitsinthatphysicalexternalfile,butyoucan queryitfromNetezzalikeyoucanqueryanormaldatabasetable. YoucanalsouseexternaltablestoexportdataoutofaNetezzatableintoafile. FromNetezza'sDataLoadingManual -AnexternaltableallowsNetezza totreatanexternalfileasada

  • 【说站】Python curses库如何使用

    Pythoncurses库如何使用1、Python内置了curses库,但是对于Windows操作系统需要安装一个补丁以进行适配。Windows下安装补全包:pip install windows-curses复制使用说明2、curses是一个应用广泛的图形函数库,可以在终端内绘制简单的用户界面。实例Python内置了curses库,其使用方法非常简单,以下脚本可以显示出当前按键对应编号:# 导入必须的库 import curses import time   # 初始化命令行界面,返回的 stdscr 为窗口对象,表示命令行界面 stdscr = curses.initscr() # 使用 noecho 方法关闭命令行回显 curses.noecho() # 使用 nodelay(True) 方法让 getch 为非阻塞等待(即使没有输入程序也能继续执行) stdscr.nodelay(True) while True:     # 清除 stdscr 窗口的内容(清除残留的符号)     stdscr.erase()     # 获取用户输入并放回对应按键的编号     # 非阻塞

  • SHGetFileInfo 报错 异常 问题

    查看代码是否使用了 ::CoInitializeEx(NULL,COINIT_MULTITHREADED);   如果是,换成在每个线程调用 ::CoInitialize(NULL);   真够蛋疼的,查了一天

相关推荐

推荐阅读