(转载)图解Java中的参数传递

简介: 今天做项目,发现了一个问题,当String作为参数传递的时候,在函数内部改变值对外部的变量值无影响,如下代码: public static void main(String[] args) { String str = "11111"; changeStr(str); System.out.println(str);//输出11111

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

  • 对于基本类型,直接拷贝值传递过去

  • 对于对象,拷贝当前对象的引用地址,然后把该地址传递过去,所以也是值传递.
原文链接:https://zhuanlan.zhihu.com/p/24556934?utm_source=qq&utm_medium=social

目录
相关文章
|
1月前
|
存储 Java
Java-参数传值
Java-参数传值
23 4
|
1月前
|
Java
【Java每日一题】— —第二十二题:类名作参数进行方法调用的传递问题。
【Java每日一题】— —第二十二题:类名作参数进行方法调用的传递问题。
23 1
|
4月前
|
前端开发 Java 数据库连接
9:参数校验-Java Spring
9:参数校验-Java Spring
30 0
|
1月前
|
存储 Java fastjson
Java泛型-4(类型擦除后如何获取泛型参数)
Java泛型-4(类型擦除后如何获取泛型参数)
32 1
|
20天前
|
缓存 Java C#
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(一)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
57 0
|
6天前
|
存储 监控 安全
泛型魔法:解码Java中的类型参数
泛型魔法:解码Java中的类型参数
26 0
泛型魔法:解码Java中的类型参数
|
1月前
|
前端开发 Java Spring
Java 新手如何使用Spring MVC 中的查询字符串和查询参数
Java 新手如何使用Spring MVC 中的查询字符串和查询参数
|
2月前
|
NoSQL Java Redis
【Java专题_09】生产环境Jvm参数设置
【Java专题_09】生产环境Jvm参数设置
|
2月前
|
Java
深入了解 Java 方法和参数的使用方法
方法是一块仅在调用时运行的代码。您可以将数据(称为参数)传递到方法中。方法用于执行特定的操作,它们也被称为函数。
104 4
|
4月前
|
Java
Java【代码分享 11】yaml配置List和Map参数对象的配置信息及类文件实例分享(效仿GatewayDynamic+DynamicDataSource的注入方法)
Java【代码分享 11】yaml配置List和Map参数对象的配置信息及类文件实例分享(效仿GatewayDynamic+DynamicDataSource的注入方法)
47 0