zoukankan      html  css  js  c++  java
  • 图解JAVA参数传递

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

    • 对于基本类型,直接拷贝值传递过去
    • 对于对象,拷贝当前对象的引用地址,然后把该地址传递过去,所以也是值传递.
  • 相关阅读:
    2011年全球手机市场十大事件
    异地求学催生网卖“生活费” 家长称不听话退款
    pygame库常用
    pygame_鼠标事件
    在Python和Django模板系统中的真值
    Django seeting配置(一)
    Django数据库配置
    转载CSS boxflex属性(弹性盒子模型)
    java volatile变量
    并发资料收集
  • 原文地址:https://www.cnblogs.com/crazyacking/p/6641543.html
Copyright © 2011-2022 走看看