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

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

参考

JAVA学习笔记之图解JAVA参数传递的更多相关文章

  1. Java学习笔记心得——初识Java

    初识Java 拿到这本厚厚的<Java学习笔记>,翻开目录:Java平台概论.从JDK到TDE.认识对象.封装.继承与多态...看着这些似懂非懂的术语名词,心里怀着些好奇与担忧,就这样我开 ...

  2. Java学习笔记之:Java简介

    一.引言 Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言和Java平台的总称.由James Gosling和同事们共同研发,并在1995年正式推出. ...

  3. Java学习笔记之:Java String类

    一.引言 字符串广泛应用在Java编程中,在Java中字符串属于对象,Java提供了String类来创建和操作字符串. 创建字符串最简单的方式如下: String str= "Hello w ...

  4. Java学习笔记之:Java引用数据类型之字符串

    一.简介 字符串广泛应用在Java编程中,在Java中字符串属于对象,Java提供了String类来创建和操作字符串. 创建字符串最简单的方式如下: String greeting = "H ...

  5. Java 学习笔记 ------第一章 Java平台概论

    本章学习目标: Java版本迁移简介 认识Java SE.Java EE.Java ME 认识JDK规范与操作 了解JVM.JRE与JDK 下载与安装JDK 一.Java版本迁移简介 书上已经表达得非 ...

  6. 【Java学习笔记之一】java关键字及作用

    Java关键字及其作用 一. 总览: 访问控制 private protected public 类,方法和变量修饰符 abstract class extends final implements ...

  7. Java学习笔记三十一:Java 包(package)

    Java 包(package) 一:包的作用: 如果我们在使用eclipse等工具创建Java工程的时候,经常会创建包,那么,这个包是什么呢. 为了更好地组织类,Java 提供了包机制,用于区别类名的 ...

  8. 【Java学习笔记之一】 java关键字及作用

    Java关键字及其作用 一. 总览: 访问控制 private protected public 类,方法和变量修饰符 abstract class extends final implements ...

  9. Java学习笔记之:Java 流

    一.介绍 Java.io包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io包中的流支持很多种格式,比如:基本类型.对象.本地化字符集等等. 一个流可以理解为一 ...

随机推荐

  1. echarts x轴坐标文字显示不全

    在echarts中应用柱状图或者折线图时,当数据量过多的时候,X轴的坐标就会显示不全(如下图图一),在ECharts图表组件内部有一个机制,用于统计xAxis坐标刻度的个数和图表宽度,从而会自动调整刻 ...

  2. zoj3696(泊松分布)

    p(k)=(y^k) / (k!) * e^(-y) 其中的y就是平均值 k就是我们要求的大小. Alien's Organ Time Limit: 2 Seconds      Memory Lim ...

  3. ios 一个正则表达式测试(只可输入中文、字母和数字)

    一个正则表达式测试(只可输入中文.字母和数字) 在项目中碰到了正则表达式的运用,正则还是非常强大的,不管什么编程语言,基本上都可以用到.之前在用java时特别是对用户名或密码使用正则非常爽,写 脚本上 ...

  4. 通过python3学习编码

    简介 今天在写python程序的时候,遇到了编码问题,今天,我准备好好了解一下编码问题 ASCII编码 计算机是美国人发明的,最初只有不超过256字符需要编码,1字节能编码2**8个,所以ASCII编 ...

  5. 知问前端——html+jq+jq_ui+mySql+ajax

    **************************************************************************************************** ...

  6. 基于ZooKeeper的服务注册中心

    本文介绍基于ZooKeeper的Dubbo服务注册中心的原理. 1.ZooKeeper中的节点 ZooKeeper是一个树形结构的目录服务,支持变更推送,因此非常适合作为Dubbo服务的注册中心. 注 ...

  7. c++拷贝构造函数,深拷贝,浅拷贝,对象内存

    https://blog.csdn.net/lwbeyond/article/details/6202256 防止默认拷贝发生 通过对对象复制的分析,我们发现对象的复制大多在进行“值传递”时发生,这里 ...

  8. 浅析Linux中的进程调度

    2016-11-22 前面在看软中断的时候,牵扯到不少进程调度的知识,这方面自己确实一直不怎么了解,就趁这个机会好好学习下. 现代的操作系统都是多任务的操作系统,尽管随着科技的发展,硬件的处理器核心越 ...

  9. 解决MySQL数据库同步1236错误

    1.报错如下: Got fatal error from master when reading data from binary log: 'The slave is connecting usin ...

  10. 【我的Android进阶之旅】Android 7.0报异常:java.lang.SecurityException: COLUMN_LOCAL_FILENAME is deprecated;

    之前开发的一个和第三方合作的apk,在之前公司的 Android 5.1 系统的手表上运行正常,今天在公司新开发的 Android 7.1系统的手表上运行的时候,使用 DownloadManager ...