博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
图解JAVA参数传递
阅读量:5992 次
发布时间:2019-06-20

本文共 2442 字,大约阅读时间需要 8 分钟。

今天做项目,发现了一个问题,当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中只有值传递:

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

转载地址:http://nntlx.baihongyu.com/

你可能感兴趣的文章
Clojure:让我兴奋的编程语言
查看>>
《IPv6精髓(第2版)》——第6章 QoS6.1 QoS基础
查看>>
《Adobe Illustrator CC经典教程》—第0课0.13节使用“外观”面板
查看>>
N 个免费 DevOps 开源工具,没用过,至少应该了解!
查看>>
《有效的单元测试》一2.4 独立的测试易于单独运行
查看>>
IBM 宣布向 Node 基金会捐赠 Express 框架
查看>>
《好学的C++程序设计》——1.1 计算机怎样计数
查看>>
Docker技术入门与实战(第2版)3.2 查看镜像信息
查看>>
《妥协的完美主义:优秀产品经理的实践指南(卷二)》一2.3 团队内部组织管理...
查看>>
《Ansible权威指南 》一1.3 为什么选择Ansible
查看>>
《STM32库开发实战指南:基于STM32F4》----3.2 STM32能做什么
查看>>
《Adobe Flash CS5中文版经典教程》——1.14复习
查看>>
《 短文本数据理解》——1.3短文本理解框架
查看>>
oracle中使用SQL递归语句
查看>>
《HTML5移动Web开发实战》—— 1.2 确定网站的适用移动设备
查看>>
《C++ 黑客编程揭秘与防范(第2版)》——6.3 PE结构的3种地址
查看>>
一位真正的科学思想家: 纪念人工智能之父Marvin Minsky教授
查看>>
《JavaScript设计与开发新思维》——2.4 关键的开发方法
查看>>
IDG2016TMT战略:大量资本将投向人工智能、消费升级、泛娱乐
查看>>
《精通移动App测试实战:技术、工具和案例》一2.2 JUnit在Android开发中的应用...
查看>>