Java参数传递
Java的参数传递分2种,按值传递和按址传递。
先看一段代码:
public class TransferValueTest {
    public static void change(int numC, String strC, int[] aC) {
        numC = 1;
        strC.substring(1);
        aC[0] = 1234;
    }
    public static void main(String args[]) {
        int num = 123;
        String str = "abc";
        int[] a = {1,12,123};
        change(num, str, a);
        System.out.println(num);  //8种基本类型按值传递
        System.out.println(str);  //特殊
        System.out.println(a[0]); //对象按址传递
    }
}
执行结果:
123 abc 1234
执行程序后,为什么 num, str的值未改变,a[0]的值发生改变了呢?
这跟Java的参数传递方式有关,Java的参数传递方式分2种:
1.按值传递(by value)
按值传递指每次传递参数时,把参数的原始数值拷贝一份新的,把新拷贝出来的数值传递到方法内部,在方法内部修改参数时,修改的是新拷贝的值,而原始的值不发生改变。
说明:这种方式传递参数,参数的原始值不发生变化。
Java的8种基本类型参数传递属于这种情况。
通过返回修改后的值来为变量赋值,可以强制改变按值传递参数的值。
2.按址传递(by address)
按址传递指每次传递参数时,把参数在内存中的存储地址传递到方法内部,在方法内部通过存储地址改变对应存储区域的内容。由于在内存中固定地址的值只有一个,即2个引用都指向同一个内存地址,所以当方法内部修改了参数的值以后,指向这个固定内存地址的引用也受影响,值发生变化。
说明:这种方式传递参数,在方法内部修改参数的值时,参数的原始值也发生变化。
引用数据类型,包括类、数组和接口,属于这种传递方式。
通过在方法内部生成新变量的方法可以避免修改按址传递参数的值。
例如上边可以在方法内部通过生成新数组,然后将参数值一一赋值新数组,这样修改新数组的值,不会影响到参数原始值。
很奇怪,String应该是按址传递,为什么上边str截取字符串后,传递参数的原始值没有发生变化呢?
查看JDK文档,文档基于1.8+
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
String 被 final 修饰,在堆内存的值不可改变,每次改变时,堆内存都会分配一块新的内存地址,String引用指向新的地址。
在上边的例子中,参数str传递给方法参数strC后,引用str和strC都指向 “abc”堆内存,当对strC.subString(1)时,会在堆内存中开辟一块新的内存地址,保存截取后的 “a”对象,同时引用strC指向新的堆内存“a”。引用str 仍然指向原堆内存 “abc”,堆内存“abc”没有发生变化,所以引用str的值不变。
 
                     
                    
                 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号 
