今天做项目,发现了一个问题,当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(),这样变化下的话,那么就和例一 一模一样了,具体图就不画了,希望对你有帮助.

3.总结

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

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

参考

最新文章

  1. 安装WAMP 及 修改MYSQL用户名 、 密码
  2. 淘宝web前端开发岗面试经历及感悟
  3. Mod4-PHP编码规范
  4. 《BI那点儿事》数据流转换——查找转换
  5. PLSQL 逻辑多线程
  6. 我对java反射机制的理解
  7. Android 4.2蓝牙介绍
  8. JQuery常用实用的事件[较容易忽略的方法]
  9. 《Cocos2d-x实战 JS卷 Cocos2d-JS开发》上线了
  10. Java基础之参数传递
  11. PHP-变量(www.w3school.com.cn/php)
  12. java链接mysql添加中文和模糊查询
  13. MXBridge - 插件式JS与OC交互框架
  14. hdu1051 Wooden Sticks---贪心
  15. 基于Spring Cloud、JWT 的微服务权限系统设计
  16. to_char与to_date的区别
  17. 002.LVS管理工具的安装与使用
  18. JqGrid: paging int asp.net
  19. 转:git合并冲突解决方法
  20. 转载:2.2 Nginx配置的通用语法《深入理解Nginx》(陶辉)

热门文章

  1. VC启动一个新线程的三种方法
  2. webpack配置(二)
  3. LAMP集群项目二 初始化系统
  4. 【Python Programe】使用Python发送语音验证
  5. Storm-源码分析-Topology Submit-Nimbus-mk-assignments
  6. zipline整体架构
  7. 搭建wordpress
  8. 如何在 cmd 中打开设备管理器,如何找到打开其他设备的命令?
  9. python web框架 django 工程 创建 目录介绍
  10. volatile变量,java内存模型