4

Javaの「すべての値渡し」の概念と少し混乱しています。

次のコードを検討してください。

class Test {
    Integer A;
    String B;
    ...

    void SetVar(Object??? var, Object value) {
        // Set A variable to the value (considering that it's possible)
    }
}

次のコードがおよびに設定されるSetVarように関数をコーディングできますか??A2BHi

void Init() {
    SetVar(this.A, 2);
    SetVar(this.B, "Hi");
}
4

7 に答える 7

2

はい、できます。リフレクション Java API を使用する。

class Test{
    void SetVar(Field field, Object value) throws 
                       IllegalArgumentException,IllegalAccessException {
         field.set(this, value);
    }

    public static void main(String[] args){
     Test test =new Test();
         test.SetVar(Test.class.getDeclaredField("A"), 2);
         test.SetVar(Test.class.getDeclaredField("B"), "Hi");
    }
  }
于 2012-10-15T12:12:21.650 に答える
2

簡単に言えば、=既存の参照に値を (演算子を使用して) 再割り当てしても、元の参照が指しているオブジェクトは変更されません。

Java での大きな誤解は、人々がそれらを 2 種類の変数であると考えていることです。

  • プリミティブ(int、boolean など)
  • 参照(整数、ブール、カスタム オブジェクトなど...)

Javaは参照を使用しません。参照という言葉は誤称です。

Java は、オブジェクトを操作する代わりにポインターのみを使用します。

色合いをよりよく理解するには: http://javadude.com/articles/passbyvalue.htm

あなたのケースに関しては、Java命名規則をスキップしたとしても(ただし、それは別の主題です)、次のようにして「問題」を解決できます。

void SetVar(Integer value) {
        this.A = value;
}

実際、(あなたが行ったように) ローカル パラメータとして渡す場合、Java は のみに焦点を合わせているためA、このローカル パラメータは参照のコピーをApassed-by-value表します。したがって、変更しても初期参照には影響しません。

于 2012-10-15T12:12:55.600 に答える
1

はい、Java は値渡しですが、特定のメソッドにオブジェクトを渡すときは、実際にはそのオブジェクトへの参照 (ポインター) を渡していることも認識しておく必要があります。あなたの場合、2 つの引数ABも不変です。つまり、に渡された元のオブジェクトを置き換えるのではなく、それらを表すローカル変数のみを再割り当てできますSetVar

于 2012-10-15T12:06:01.713 に答える
1

一般的には依存します。この特定のケースでは、A と B は不変であるため、できません。

セッターを持つ変更可能なオブジェクトがある場合、setVarメソッドでそのプロパティの一部を変更できます。

var.setValue(value);

ただし、元のオブジェクトが指す参照を変更することはできません (値によって渡されたため)。

var = someOtherObject; //no effect on the reference in the calling code

詳細については、 Java FAQの一部であるこの投稿を参照してください。

于 2012-10-15T12:00:37.710 に答える
0
void SetVar(Object??? var, Object value) {

なる

void SetVar(final Integer var, final String value) {
   A=var; // use minuscule for field like  a=var;
   B=value; // this. is not necessary here
}

コンストラクタで初期化:

Test (final Integer var, final String value){
   setVar(var, value);
} 
于 2012-10-15T12:04:11.950 に答える
0

IntegerおよびString不変であるため、値を変更することはできません。初期AB後は、変数に新しい値を割り当てるだけです。SetVarまた、変数の内部varはメソッドに対してローカルであるため、指されているオブジェクトを変更してvarも、外部の呼び出し元には影響しません。

于 2012-10-15T12:04:14.273 に答える
0

あなたの例では this.A を setVar() メソッドに渡していますが、 this.A は null であるため、これは役に立ちません。ただし、できることは、this.A をホルダーにして、そのホルダーを setVar() メソッドに渡すことです。

以下のコードは、あなたが望むことを行います。フィールド a と b に IntegerHolder と StringHolder を使用し、クラスの構築時に空のホルダー オブジェクトでホルダー フィールドを初期化します。

次に setVar() を呼び出すと、フィールド a と b の値は設定されず、代わりにホルダーの内容が設定されます。

public class Test
{
    IntegerHolder a = new IntegerHolder();
    StringHolder b = new StringHolder();

    void setVar(IntegerHolder var, Integer value) {
        var.value = value;
    }

    void setVar(StringHolder var, String value) {
        var.value = value;
    }

    class IntegerHolder
    {
        Integer value;
    }

    class StringHolder
    {
        String value;
    }

}
于 2012-10-15T12:14:14.900 に答える