Java方法参数传递机制

1.总述

      Java中参数传递是值传递!!!(很重要)。

如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的值不会改变原始的值.

  如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的地址,所以不会改变参数的值。

2.细述

参数类型:

  • 实参:在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”,简称“实参

    changeStr(str); //这里的str就是实参

  • 形参:是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数,简称“形参”

    static void changeStr(String str) //这里的参数str就是形参

实参传递给方法:

就是通过方法的传递机制进行传递

  • 值传递:是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数复制,在函数中对参数进行修改不会影响到实际参数)、

    复制的是参数的引用(地址值),并不是引用指向的存在于堆内存中的实际对象

  • 引用传递:是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。(传地址,会影响实际参数

方法参数有基本数据类型、引用数据类型

  • 基本数据类型string、int等类型,很明显这里的str并没有被改变,这里很明显的看到出来:java使用的是值传递

  • public static void changeStr(String str){
        str="welcome";
    }
    
    /***
     * 主要是值传递
     */
    private static void changeStrDemo() {
        String str="1234";
        changeStr(str);  //这里的str就是实参
        System.out.println(str);  //输出1234,而不是welcome
    } 

  • 引用数据传递:

  • 这里可以看到调用方法后user中的name属性的值改变了,但是实际上java传递参数还是通过值传递,这里之所以会有产生引用传递的错觉:

    因为复制的是地址!!!

    main方法中的user是一个引用(也就是一个指针),它保存了User对象的地址值,当把user的值赋给pass方法的user形参后,即让pass方法的user形参也保存了这个地址值,即也会引用到堆内存中的User对象

    上面代码中,之所以产生引用传递的错觉,是因为参数保存的是实际对象的地址值,你改变的只是地址值指向的堆内存中的实际对象,并没有真正改变参数,参数的地址值没有变。

Demo0315 demo0315 = new Demo0315();

User user = new User();
user.setName("张三");
user.setAge(18);

System.out.println("pass方法调用前,user=" + user.toString());
demo0315.pass(user);
System.out.println("pass方法调用后,user=" + user.toString());

 public void pass(User user) {
        user.setName("李四");
        System.out.println("pass方法中,user = " + user.toString());
    }
    
    
这里的输出:
pass方法调用前,user=User{name='张三', age=18}
pass方法中,user = User{name='李四', age=18}
pass方法调用后,user=User{name='李四', age=18}

一个生活化例子:

引用传递:

你有一把钥匙,当你的朋友想要去你家的时候,如果你直接把你的钥匙给他了,这就是引用传递。这种情况下,如果他对这把钥匙做了什么事情,比如他在钥匙上刻下了自己名字,那么这把钥匙还给你的时候,你自己的钥匙上也会多出他刻的名字。

值传递:

你有一把钥匙,当你的朋友想要去你家的时候,你复刻了一把新钥匙给他,自己的还在自己手里,这就是值传递。这种情况下,他对这把钥匙做什么都不会影响你手里的这把钥匙。

但是,不管上面哪种情况,你的朋友拿着你给他的钥匙,进到你的家里,把你家的电视砸了(这里就是改变了那个user中属性的值)。改变的不是那把钥匙(地址值),而是钥匙打开的房子(地址值对应的实际对象)。

但是为什么基本数据类型不是砸电视呢???

因为基本数据类型的复制的直接就是参数的值,引用数据类型复制的参数是数据的地址(在内存当中的地址),实际上,在引用数据类型传值的时候,复制的参数是没有改变的即地址没有改变(这就是典型的值传递)

你可能感兴趣的:(java,java,开发语言)