【问题标题】:Modifying an object or primitive using a void method [closed]使用 void 方法修改对象或原语 [关闭]
【发布时间】:2014-01-27 16:32:32
【问题描述】:

考虑以下代码中的第 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”。

【问题讨论】:

  • 我强烈建议您从 Java 初学者书籍或 Oracle 教程开始。
  • Is Java "pass-by-reference"? 的可能重复项
  • 第 1 行和第 2 行差别不大。我们该如何解释?

标签: java string void primitive


【解决方案1】:

在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.

【讨论】:

    【解决方案2】:

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

    1) 字符串在设计上是不可变对象,因此一旦构建就不能更改。只是为了清楚起见,像这样:

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

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

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

    3) 参数传递在java中总是按值;这意味着在赋值左侧使用参数永远不会在方法调用之外产生影响;相反,您只需踩到您收到的参数的值。如果参数是原始类型还是对象类型,这并不重要。如果参数是对象类型,参数传递也是按值传递的,但是你复制到方法调用堆栈的是对对象的引用的副本。因此,在您的 modifyStringXX 方法中,您唯一实现的就是踩到对参数的引用,但您永远不会看到这些方法之外的效果。

    【讨论】:

      猜你喜欢
      • 2017-11-11
      • 2013-01-05
      • 1970-01-01
      • 1970-01-01
      • 2017-09-11
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多