使用void方法修改对象或基元

时间:2014-01-09 08:16:32

标签: java string void primitive

考虑以下代码中的第2行和第3行......

class ModifyObjects {
    static void modifyString1(String s){
        s = "xyz";
    //Or any other operations
    }

    static String modifyString2(String s){
        s = "xyz";
        return s;
    //Or any other operations
    }

    static void modifyPrimitive1(int i){
        i=9;
    }

    static int modifyPrimitive2(int i){
        i=9;
        return i;
    }
}

public class Operations {

    public static void main(String[] args) {
    // TODO Auto-generated method stub

    String st1 = "abcd";
    String st2 = "qwerty";
    String st3;

    int i1=0, i2;

    st1 = "xyz";                          //line 1
    System.out.println("st1: " + st1);     

    ModifyObjects.modifyString1(st2);
    System.out.println("st2: " + st2);     //line 2

    st3 = ModifyObjects.modifyString2(st2);
    System.out.println("st3: " + st3);

    System.out.println("st2: " + st2);

    ModifyObjects.modifyPrimitive1(i1);
    System.out.println("i1: " + i1);            //line 3

    i2 = ModifyObjects.modifyPrimitive2(i1);
    System.out.println("i2: " + i2);    
    }
}

第2行给出st2为qwerty(不修改。应该是xyz。)      第3行给出i1 = 0(不修改。应该是9。)

这看起来有点奇怪。这是输出:

 st1: xyz
 st2: qwerty
 st3: xyz
 st2: qwerty
 i1: 0
 i2: 9

同样在第1行创建了一个新的字符串对象“xyz”吗?我认为“abcd”就是从这里引用的。

2 个答案:

答案 0 :(得分:3)

在Java中对对象的引用按值传递......

    1.  st1: xyz

    Reason : you are not returning anything...

    2.  st2: qwerty

    Reason :You are not storing the returned value in st2. you should do,

        st2=ModifyObjects.modifyString1(st2);

    3.  st3: xyz

    reason : You are returning a String value and storing it in st3

    4.  st2: qwerty

    Reason : st2 is qwerty...

    5.  i1: 0  // Not reassigning value to anything

    6.  i2: 9  // returned value reassigned to i2.

答案 1 :(得分:1)

我认为你对java中字符串和参数传递的工作方式有些困惑。

1)字符串是按设计不可变对象,因此一旦构建就无法更改。为了清楚起见,这样的事情:

String s = "a";
s += "bc";
System.out.println(s);

不是修改String的值,而是创建新对象。在此代码的末尾,您创建了2个String对象:第一行中值为“a”的对象,第二行中值为“abc”的对象。 (这是一种自愿的简化,因为java编译器可能决定优化此代码,但无论如何它都是正确的)

2)如果您需要一个可变的String对象,java会为您提供StringBuilder对象(如果您需要同步版本,则为StringBuffer)。如果你需要将东西附加到String,它实际上是推荐的习惯用法。

3)参数传递在java中始终按值;这意味着使用赋值左侧的参数将永远不会在方法调用之外产生影响;相反,您只需踩到您收到的参数的值。如果参数是基本类型或对象类型,则无关紧要。如果参数是对象类型,则参数传递也是值,但是复制到方法调用堆栈的是对象引用的副本。所以,在你的modifyStringXX方法中,你唯一能做到的就是踩参数,但你永远不会看到那些方法之外的效果。