日期:2014-05-20  浏览次数:20693 次

调用方法改变对象的值问题,String,Integer经过调用方法不改变值
Java code
public class ChangeStrDemo {
    
    public static void main(String agrs[]) {
        Integer i = 12;
        changInteger(i);
        System.out.println(i);

        String str = "1234";
        changStr(str);
        System.out.println(str);
        
        A1 a1=new A1(12,12);
        changA1(a1);
        System.out.println(a1);
        
    }
    public static void changStr(String str) {
        str = "welcome";
    }

    public static void changInteger(Integer i) {
        i = 10;
    }
    public static void changA1(A1 a1) {
        a1.a=10;
        a1.b=10;
    }

}

class A1 {
    public  int a;
    public int b;
    public A1(int a,int b){
        this.a=a;
        this.b=b;
    }
    @Override
    public String toString() {
        return a+"   "+b;
    }
    
}

结果:
12
1234
10 10
为什么在参数是String,Integer对象的时候,对象值不改变,参数是其他对象的时候,例如A1,对象的值改变了
参数是对象的时候,传去方法里的值不是对象地址的应用吗,改变对象的值,原先对象的值也跟着改变的吗

------解决方案--------------------
对于基础类型和字符串 值传递很好理解。

对于引用:

“引用传递” 并不得到全部人的认同。我就不认同这种说法

值传递 对 引用 来说, 此时的值 是 引用指向, 而不是 引用指向所指对象的内容

传入引用给形参之后(外面变量的指向并未改变指向),形参也指向那个对象。 然后通过形参改变对象内容

方法结束之后。外面变量访问改变内容后的对象

所以就会输出改变后的值
------解决方案--------------------
Java中的传递是值传递,changInteger(i) 把i引用的Integer对象的地址复制给changInteger(Integer i)方法中的i,也就是说方法中形参i与main方法中的i指向同一个对象(虽然二者名字相同,但是两个不同的引用变量)。在changInteger方法中使形参i重新引用另一个对象,这时,两个i指向不同的对象。其他也是这样。
------解决方案--------------------
给lz一个建议,弄清楚内存,什么作用域什么值传递引用传递的,都是浮云罢了。内存才是王道!

栈内存和堆内存:基本数据类型的变量是放在栈内存里面,因为它有先后顺序的(只要上面的数据没有出栈,下面的都有效),所以他是有一定的范围的(假如在一个方法里面的传参数,是新的变量),他是可以重复利用的。堆内存则不同,他很动态,不连续,存放的时候是自己找空位,所以一般对象是放在堆内存,后面穿过去的事引用,change方法里的对象的引用还是指向先前的那块内存,改变的也是那块内存。

初学者要深入学习java内存,很多问题都很容易理解了。
------解决方案--------------------
对于基本类型,我的理解是:(这里拿String类做例子)
main方法中,str这个引用指向字符串"1234",然后它作为参数传递给了changeStr(str),
在changeStr()方法中,一开始(还没有执行str="welcome";这条语句)时,这两个str
应该是指向同一个字符串(值),并没有分别指向一个不同的字符串(值);而在执行了
str="welcome";后,它才会新建一个String对象,str指向它,此时才存在两个String对象。
你打印一下str的hashCode就知道了,在main方法中和在执行str="welcome";这条语句之前
str的hashCode是相同的,赋值好之后就不同了!

而对于非基本类型,这个应该好理解。
------解决方案--------------------
首先应该明确一下栈和堆得概念,引用变量在栈里面,而类对象在堆里面,当一个方法运行结束了,传入方法的引用变量都会被系统回收,所以不会改变原有的值,而对对象的改变是在堆里,方法结束后并不会影响对象里的变量值