今天做项目,发现了一个问题,当String作为参数传递的时候,在函数内部改变值对外部的变量值无影响,如下代码:

 public static void main(String[] args) {String str = "11111";changeStr(str);System.out.println(str);//输出11111
    }public static void changeStr(String str){str = "22222";}

一开始很不解,后来想明白了,遂去对java参数传递做一个总结,以加深自己的基础知识.

1.基本类型传递

对于:

  • 整型: byte short int long
  • 浮点型 float double
  • 逻辑型 boolean
  • 字符型 char

四类八种基本类型来说,传递的都是值,因为这些值是直接保存在栈内存中的,所以传递的时候直接拷贝过去了.

public static void main(String[] args) {int num = 0;change(num);System.out.println(num);//输出0
    }public static void change(int numChange){numChange =5;}

结构如下图,也因此最外层的num的值并没有受到影响.

2.对象传递

2.1 例一

对象传递,本质上也都是值传递,只不过传递的值是该引用的拷贝.看下面实例和图解:

public static void main(String[] args) {Person person = new Person("aaa", 11);change(person);System.out.println(person);//输出 bbb 11
    }public static void change(Person personChange){personChange.setName("bbb");} 

结构图如下:
当执行change的时候,会把person变量的指向的地址拷贝一份给personChange,两者都指向同一个堆内存,即使后面做了set方法修改,但是对两者的执行毫无影响.

2.2例二

例二和之前的不同之处在change里面,对personChange进行了new操作.代码如下:

public static void main(String[] args) {Person person = new Person("aaa", 11);change(person);System.out.println(person);//输出 aaa 11
    }public static void change(Person personChange){personChange = new Person("bbb",12);}

结构图如下:

当执行change的时候,会把person变量的指向的地址拷贝一份给personChange,两者都指向同一个堆内存,接下new操作会在堆中重新创建一个person对象,此时personChange则指向这个对象,而原person的指向没发生变化,故输出aaa 11.

2.3 例三

例三是综合例一和例二,前面两个搞懂的话这个就很容易懂了.

public static void main(String[] args) {Person person = new Person("aaa", 11);change(person);System.out.println(person);//输出 ccc 11
    }public static void change(Person personChange){personChange.setName("ccc");personChange = new Person("bbb",12);}

结构图如下:

读者自己理解下,不懂的话再看看前面的,看看为什么输出CCC 11

2.4特殊的String

终于到最初的问题,为什么String是对象,但是却不符合上面对象传递测试出来的结果?

 public static void main(String[] args) {String str = "11111";changeStr(str);System.out.println(str);//输出11111
    }public static void changeStr(String str){str = "22222";}

原因:
因为String对象具有不可变性,所以针对操作str = "22222",在String池中不存在的时候,就是相当于str = new String(),这样变化下的话,那么就和例一 一模一样了,具体图就不画了,希望对你有帮助.
ps:如果想改变的话,可以使用Holder包装类包装String,可以参考博文:Java基础系列18:Holder技术的实现原理分析 | zifangsky的个人博客

3.总结

要理解上面的结果,就要认为Java中只有值传递:

  • 对于基本类型,直接拷贝值传递过去
  • 对于对象,拷贝当前对象的引用地址,然后把该地址传递过去,所以也是值传递.

转载于:https://www.cnblogs.com/crazyacking/p/6641543.html

图解JAVA参数传递相关推荐

  1. java备忘录模式应用场景_图解Java设计模式之备忘录模式

    图解Java设计模式之备忘录模式 游戏角色状态恢复问题 游戏角色有攻击力和防御力,在大战Boss前保存自身的状态(攻击力和防御力),当大战Boss后攻击力和防御力下降,从备忘录对象恢复到大战前的状态. ...

  2. java参数传递(超经典)

    java参数传递(超经典) 2010-10-28 16:46:29|  分类: Java |  标签:sb  changedata  strbuf  参数传递  hello   |字号 订阅 Java ...

  3. java add offer_图解Java中的5大队列!(干货收藏)

    Java 中的队列有很多,例如:ArrayBlockingQueue.LinkedBlockingQueue.PriorityQueue.DelayQueue.SynchronousQueue等,那它 ...

  4. 图解Java内存区域及内存溢出异常

    图解 Java 内存区域及内存溢出异常 在阅读 <深入理解Java虚拟机:JVM高级特性与最佳实践(第2版) >后,为了加深对 Java 内存区域的印象及理解,特意做成了思维导图. 名词解 ...

  5. java 观察者模式_图解Java设计模式之观察者模式

    图解Java设计模式之观察者模式 天气预报项目需求 天气预报设计方案 1 - 普通方案 观察者模式(Observer)原理 观察者模式解决天气预报需求 观察者模式在JDK应用的源码分析 天气预报项目需 ...

  6. 图解Java多线程设计模式

    图解Java多线程设计模式 1-4章 第一部分 第五章 生产者与消费者 第六章 读写锁 7.8.9章 第三部分 第十章 Two-phase Termination 想要结束运行中的线程 ,这张有问题, ...

  7. 图解java多线程设计模式 pdf_图解Java设计模式之状态模式

    图解Java设计模式之状态模式 APP抽象活动问题 状态模式基本介绍 状态模式的原理类图 状态模式解决APP抽奖问题 状态模式的注意事项和细节 APP抽象活动问题 请编写程序完成APP抽象活动,具体要 ...

  8. java参数传递时,究竟传递的是什么

    请问java参数传递时,究竟传递的是什么?    一直看到的答案都是参数传递时,如果是基本数据类型  那传递的就是值.如果是对象 数组等类型传递的就是地址.    大概类似与这种:图片来源   那为什 ...

  9. java参数传递的乱码问题

    java参数传递的乱码问题 编码设置的几种情况: (1)页面里统一使用utf-8格式 <%@ page contentType="text/html;charset=UTF-8&quo ...

最新文章

  1. 浅谈python+requests实现接口自动化
  2. python安装pyopenssl
  3. Python入门100题 | 第069题
  4. ASP.NET实现文件上传
  5. 一仅仅小蜜蜂(杭电2044)
  6. 从零开始入门 K8s:深入剖析 Linux 容器
  7. oracle 一次删除多张表
  8. 软件工程15 个人阅读作业1
  9. linux mysql 移动_Linux下安装MySQL
  10. 2012年总结2013展望 向岁月致敬 对未来憧憬
  11. 416亿元公有云市场:阿里173亿、腾讯50亿、华为35亿
  12. 2021年高考成绩查询2,2021年高考成绩公布后几天填报志愿
  13. java内存管理(堆、栈、方法区)
  14. python的重试库tenacity用法以及类似库retry、requests实现
  15. Ubuntu下安装php7.1的gd,mysql,pdo_mysql扩展库
  16. 一文带你了解夜间灯光数据
  17. python错误:ImportError: DLL load failed: 找不到指定的程序,from PyQt6 import QtCore, QtGui, QtWidgets
  18. oracle临时表的创建
  19. linux学习日志,linux学习日记范文
  20. ubuntu 20.04 修改文件夹默认图标

热门文章

  1. java 生成token代码_java token生成和校验的实例代码
  2. f3arra1n3.4.1版本_GDB 10.1版本发布了
  3. oracle leg函数,oracle对象 约束索引 游标 函数
  4. 小说阅读网站设计HTML,40多个漂亮的网页表单设计实例
  5. mysql 值到99999后不增值了_MySQL必知必会3
  6. python读取配置文件使用_python 使用 ConfigParser 读取和修改INI配置文件
  7. Java基础知识融合(Arraylist集合,多态,继承,封装,包装类,循环嵌套,if嵌套等等)
  8. 互联网晚报 | 4月11日 星期一 | 苏州放宽住房限售;苹果确认开始在印度生产iPhone 13;民航局将上报民航专项检查方案...
  9. 2022中国私域流量管理研究报告
  10. 互联网日报 | 3月7日 星期日 | 《你好,李焕英》成中国影史票房亚军;丰巢新增智能存包柜业务;特斯拉推出内部社交平台...