java中的值传递

 对象和对象引用的对应关系:

(1)一个对象引用可以指向0个或1个对象(一根绳子可以不系汽球,也可以系一个汽球); 

(2)一个对象可以有N个引用指向它(可以有N条绳子系住一个汽球)。 

public static void main(String[] args) {
        Test test1 = new Test();
        Test test2 = new Test();
        test1 = test2;//内存泄漏,test1 new出来的对象没有引用指向,称为gc回收的对象
    }

从存储空间上来说,对象一般存储在堆中,而引用存储在栈中。 

值传递:如果传入方法的是基本类型,你就得到此基本类型的一份拷贝。如果是传递引用,就得到引用的拷贝。 

public class Test {

    //基本类型的参数传递  
    public static void testBasicType(int m) {  
        System.out.println("m=" + m);//m=50  
        m = 100;  
        System.out.println("m=" + m);//m=100  
  
    }
    
    //改变了原来的sMain,因为s和sMain其实是指向同一地址
    public static void add(StringBuffer s) {  
        s.append("_add");  
    }  
    
    //没改变原来的sMain,因为s和sMain指向了不同地址,
    public static void changeRef(StringBuffer s) {  
        s = new StringBuffer("Java");  
    } 
    //String类具有不变性,这里虽然只是+"111",但对于String来说,其实跟new是一回事,所以原s没变。
    public static void changeS(String s) {
        s = s + "111";
    }
    public static void main(String[] args) {
        int i = 50;  
        testBasicType(i);  
        System.out.println(i);//i=50  
        StringBuffer sMain = new StringBuffer("init");  
        System.out.println("sMain=" + sMain.toString());//sMain=init  
        add(sMain);  
        System.out.println("sMain=" + sMain.toString());//sMain=init_add  
        changeRef(sMain);  
        System.out.println("sMain=" + sMain.toString());//sMain=init_add  
        String s = new String("test");
        changeS(s);
        System.out.println("s:" + s);//s:test,注意以下String类的特殊性
    }

}

总结:

A a = new A();//a是引用,new A()是对象

引用存的是地址,不是对象本身。所以如果传参是引用的话,在函数中,如果对于拷贝引用,没有改变其地址,则对拷贝引用的改变,就是对原参数的改变;如果对拷贝引用改变了地址,比如new了一个新对象,则其改变就不再是对原参数的改变了,原参数不会有任何变化,当然如果在这种情况下,还想对原参数产生影响,可以将这个拷贝引用return回去即可。

原文地址:https://www.cnblogs.com/cing/p/8561690.html