【问题标题】:Changing the value being passed through the parameter更改通过参数传递的值
【发布时间】:2015-04-08 17:40:23
【问题描述】:

我正在测试是否可以通过参数传递静态变量 x 来更改它的值,但我发现你不能那样做。

public class Test {
static int x;

static void changeX(int x_) {
    x_ = 50;

}

public static void main(String args[]) {

    changeX(x);
    System.out.println(x);//it prints out zero because the static variable did not get changed


}

}

如果我们这样做,我们可以改变它:

public class Test {
static int x;

static void changeX(int x_) {
    x = 50;

}

public static void main(String args[]) {

    changeX(x);
    System.out.println(x);

}

}

这意味着您必须直接引用静态变量才能更改它。好的。现在。我的问题是,有没有办法通过参数传递类变量来更改类变量,而不在实现中引用它?基本上,有没有办法以某种方式使用第一种方式?谢谢。

【问题讨论】:

  • 不,至少不是原始类型或包装器Integer 类型。
  • Java总是按值传递。您不能通过函数调用更改传入的原始参数值。
  • 我想如果你改变参数中的值,通过参数传递的值也会改变。 x.x 真的没有办法吗?如果能以某种方式完成,那将非常有用。
  • 你可以使用反射来做到这一点
  • @nmelssx primitive 类型永远不可能通过函数调用更改外部值。您可以通过函数调用更新对象引用,但这仅适用于非不可变类型。您可以通过函数调用直接使用引用来更新对象引用(因为它指向相同的内存位置),但是您不能将参数重新分配给另一个对象引用并更新原始引用,因为 引用按值传递。

标签: java parameters reference parameter-passing


【解决方案1】:

可以实现您的要求,但您需要注意细微的限制。您可以修改传递给方法的对象引用,但不能重新分配方法中的引用并更改原始对象。

Java 总是按值传递。时期。 对象引用是按值传递的,但是通过这些引用(指向相同的内存位置),您可以通过参数修改方法内部的对象。

不能以这种方式修改基元(intfloatboolean 等),它们总是按值传递。您也不能修改不可变对象(例如String),因为它们不能使用公共接口进行更改。

考虑这个简单的例子,它测试创建一个具有一些可修改字段、按值和按引用的对象(它通过对象引用进行修改,它本身是按值传递的):

public class ParameterPassingTest {
    static SomeObject someStaticObject;

    public static void main(String[] args) {
        // initialize a static object reference
        someStaticObject = new SomeObject("I am a static Object", 10);

        System.out.println("My static object before: " + someStaticObject);

        // try modifying the reference by value
        modifySomeObjectByValue(someStaticObject);
        // try printing the value, it will be the same
        System.out.println("My static object after mod-by-value: " + someStaticObject);

        // now, try modifying by object reference
        modifySomeObjectByReference(someStaticObject);

        // print again. new values should be observed
        System.out.println("My static object after mod-by-reference: " + someStaticObject);
    }

    // this method tries to modify the original object by assigning directly to the method parameter. It won't work.
    public static void modifySomeObjectByValue(SomeObject someObject) {
        SomeObject newObject = new SomeObject("I am another object, from a local method", 20);
        someObject = newObject; // try to modify the original object by assigning to the parameter directly
    }

    // this method tries to modify the original object by using the object's public interface. It works.
    public static void modifySomeObjectByReference(SomeObject someObject) {
        // try to modify the original object by using the reference passed in
        someObject.setaString("I have been modified by a method");
        someObject.setAnInt(50);
    }
}

// simple, generic class object with some fields.
class SomeObject {
    String aString;
    int anInt;

    public SomeObject(String aString, int anInt) {
        this.aString = aString;
        this.anInt = anInt;
    }

    public String getaString() {
        return aString;
    }

    public void setaString(String aString) {
        this.aString = aString;
    }

    public int getAnInt() {
        return anInt;
    }

    public void setAnInt(int anInt) {
        this.anInt = anInt;
    }

    @Override
    public String toString() {
        return "aString = " + getaString() + " | anInt = " + getAnInt();
    }
}

这会产生输出:

My static object before: aString = I am a static Object | anInt = 10
My static object after mod-by-value: aString = I am a static Object | anInt = 10
My static object after mod-by-reference: aString = I have been modified by a method | anInt = 50

【讨论】:

    【解决方案2】:

    Java 总是将原语作为值传递。另一方面,对象总是作为引用传递。在第二个示例中,您访问的是静态属性x,而不是参数x_。 此外,static 不保护属性不被重写。它将一个属性绑定到类(没有static 属性绑定到对象)。也许你的意思是final

    编辑:更正了一个错字。

    【讨论】:

    • 如此简短的回答。没办法。
    • “另一方面,对象总是作为引用传递” 不,它们不是。对象 references 是按值传递的,这意味着您获得了引用的副本。但是,您可以使用该引用来更改它指向的对象,只要它不是不可变的(如字符串)。如果您尝试将传递的参数引用重新分配给另一个对象,它不会更新原始引用。
    猜你喜欢
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 2014-03-19
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2020-02-18
    相关资源
    最近更新 更多