【问题标题】:Pass by value or Pass by reference in Java: Issues with immutable and mutable objects [duplicate]Java中的按值传递或按引用传递:不可变和可变对象的问题[重复]
【发布时间】:2013-09-23 14:11:53
【问题描述】:

java 是按值传递还是按引用传递。我的问题促使我写了这个class,以便我可以自信地回答。我想知道我注意到immutablemutable 对象可能存在问题。我要问的是,在查看了这个简单的class 的输出后,正确答案是什么。

class

package notsure.tests;

public class PassingValues {

static Object[] passingValueMethod(int intValue, StringBuilder strValue){
    int recievedIntValue = intValue;
    StringBuilder recievedStrValue = strValue;

    System.out.println("------Let's see mutable objects------");
    System.out.println("----In the called method-------");
    System.out.println("-----New References Without Modification-----");
    //No modification
    System.out.println("Recieved integer: "+recievedIntValue);
    System.out.println("Received StringBuilder: "+ recievedStrValue);
    System.out.println();

    System.out.println("---- New refernces With Modification-----");
    //Modification
    recievedStrValue.append(", I am modified in a method() through a reference ");
    System.out.println("Recieved StringBuilder: "+ recievedStrValue);
    recievedIntValue++;
    System.out.println("Recieved integer: "+recievedIntValue);
    System.out.println();
    //Evaluate the parameter values
    System.out.println("----Received parameter variables current values-----");
    System.out.println("StringBuilder: "+strValue+" \nInteger: "+intValue);
    return new Object[]{recievedIntValue, recievedStrValue};

}
static String passingImmutable(String str){
    String recievedStr = str;
    System.out.println("-----In passpassingImmutable() ------");
    System.out.println("---------without modification------");
    System.out.println("Recieved string with local ref: "+recievedStr);
    System.out.println();
    System.out.println("------With modification-------");
    recievedStr = str+" I am modified";
    System.out.println("Recieved string with local ref: "+recievedStr);
    System.out.println();
    System.out.println("----Let's see the parameter value content---");
    System.out.println("Recieved string with param ref: "+str);
    return recievedStr;
}
public static void main(String[] args) {
    Object[] object = new Object[2];
    int integer = 10;
    StringBuilder stringBuilder=new StringBuilder("Stringbuilder");
    object = passingValueMethod(integer,stringBuilder);
    System.out.println();

    System.out.println("---------Back in Main-------- ");
    System.out.println("----Values returned----");
    for(Object obj:object){
        System.out.println(obj);
    }
    System.out.println();
    System.out.println("----Variables in Main-----");
    System.out.println(integer);
    System.out.println(stringBuilder);
    System.out.println("NOTE: even local Object(except primitive) reference reflect changes");
    System.out.println();
    System.out.println("-----Let's use immutable objects-----");
    String str = "I am a string";
    System.out.println("Value in main before method call: "+str);
    System.out.println();
    passingImmutable(str);
    System.out.println();
    System.out.println("--------------Back in main----------");
    System.out.println("String Value retuned: "+str);
    System.out.println();
    System.out.println("String passed(main reference) value: "+str);

}

}

output

------Let's see mutable objects------
----In the called method-------
-----New References Without Modification-----
Recieved integer: 10
Received StringBuilder: Stringbuilder

---- New refernces With Modification-----
Recieved StringBuilder: Stringbuilder, I am modified in a method() through a reference 
Recieved integer: 11

----Received parameter variables current values-----
StringBuilder: Stringbuilder, I am modified in a method() through a reference  
Integer: 10

---------Back in Main-------- 
----Values returned----
11
Stringbuilder, I am modified in a method() through a reference 

----Variables in Main-----
10
Stringbuilder, I am modified in a method() through a reference 
NOTE: even local Object(except primitive) reference reflect changes

-----Let's use immutable objects-----
Value in main before method call: I am a string

-----In passpassingImmutable() ------
---------without modification------
Recieved string with local ref: I am a string

------With modification-------
Recieved string with local ref: I am a string I am modified

----Let's see the parameter value content---
Recieved string with param ref: I am a string

--------------Back in main----------
String Value retuned: I am a string

String passed(main reference) value: I am a string

【问题讨论】:

  • 你用谷歌搜索过这个问题的解释吗?
  • Java 是按值传递的。对象值是引用。
  • 不清楚为什么你会“不希望被问到”这个问题 - 对答案充满信心不是更好吗?
  • Java 总是按值传递。很难理解 Java 将对象作为引用传递,而这些引用是按值传递的。 (引自埃尔多兰多)
  • @PhilippSander 确实,我觉得很有趣的是,错误的理解(Java 是按引用传递)远没有天真但正确的理解(Java 是按值传递但忽略它通过值传递引用)

标签: java parameter-passing mutable immutability


【解决方案1】:

Java 按值传递引用,尽管实际上是按值传递,但它给人一种按引用传递的感觉。

public class Main{

    public static void main(String[] args) {
        Vector3d vectorTest=new Vector3d(1,2,3);
        System.out.println(vectorTest.x); //prints 1
        affectVector(vectorTest);
        System.out.println(vectorTest.x); //prints 100
        replaceVector(vectorTest);
        System.out.println(vectorTest.x); //still prints 100
    }

    public static void affectVector(Vector3d vectorIn){
         vectorIn.x=100; 
    }

    public static void replaceVector(Vector3d vectorIn){
         //this method has no external effect because the reference vectorIn is immediately overrwritten
         vectorIn=new Vector3d(0,0,0); //the reference vectorIn is completely changed
    }


}

您可以看到,因为引用是按值传递的,您仍然可以访问它所引用的对象,但是如果您替换引用,那么您将“引用”到另一个对象,并且在方法之外没有任何影响。

我在试图描述这一点时使用的类比是邮政地址。参考是您用来向对象发送信件(说明)的邮政地址。您可以将该地址复制到多张纸上,但它仍会将信件发送到同一所房子。复制的是邮政地址,而不是“房子”

【讨论】:

    猜你喜欢
    • 2018-07-20
    • 2012-03-12
    • 2013-09-15
    • 2013-12-02
    • 2020-03-17
    • 2021-11-04
    • 2019-05-07
    • 2014-09-10
    • 2012-01-05
    相关资源
    最近更新 更多