图解JAVA参数传递

今天作项目,发现了一个问题,当String做为参数传递的时候,在函数内部改变值对外部的变量值无影响,以下代码:java

 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

四类八种基本类型来讲,传递的都是值,由于这些值是直接保存在栈内存中的,因此传递的时候直接拷贝过去了.spa

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的值并无受到影响.code

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方法修改,可是对二者的执行毫无影响.blog

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.class

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中只有值传递:

  • 对于基本类型,直接拷贝值传递过去
  • 对于对象,拷贝当前对象的引用地址,而后把该地址传递过去,因此也是值传递.
相关文章
相关标签/搜索