14

初心者のJavaの質問ですが、以下の例で値による呼び出し(または参照)がどのように機能しているか理解できません-

カスタム文字列オブジェクトがメソッドを終了した後、文字列値が変更されないのはなぜですか。?Dateのような他のクラスと同じです。

public class StringMadness {

public static void main(String[] args) {
    String s = "Native String";
    CustomStringObject cs = new CustomStringObject();
    System.out.println("Custom String Before: " + cs.str);
    hello(cs);
    System.out.println("Custom String After: " + cs.str);

    System.out.println("Native String Before: " + s);
    hello(s);
    System.out.println("Native String After: " + s);
}

private static void hello(String t) {
    t = "hello " + t;
}

private static void hello(CustomStringObject o) {
    o.str = "hello " + o.str;
  }
}

class CustomStringObject {

String str = "Custom String";
}
4

5 に答える 5

25

これら2つの方法を比較してください。

private static void hello(String t) {
    t = "hello " + t;
}

private static void hello(CustomStringObject o) {
    o.str = "hello " + o.str;
}

最初のケースでは、に新しい値を割り当てていますt。これは呼び出し元のコードには影響しません。パラメータの値を変更するだけで、すべての引数はJavaの値で渡されます。

2番目のケースでは、に新しい値を割り当てていますo.str。これは、の値が参照するオブジェクト内のフィールドの値を変更することoです。呼び出し元はまだそのオブジェクトへの参照を持っているため、呼び出し元にはその変更が表示されます。

つまり、Javaは常に値渡しを使用しますが、クラスの場合、変数(または実際には他の式)の値はオブジェクトではなく参照であることを覚えておく必要があります。これを確認するためにパラメータの受け渡しを使用する必要はありません。

Foo foo1 = new Foo();
Foo foo2 = foo1;
foo1.someField = "changed";
System.out.println(foo2.someField) // "changed"

ここでの2行目は、の値をにコピーしますfoo1。2foo2つの変数は同じオブジェクトを参照しているため、アクセスに使用する変数は関係ありません。

于 2012-08-03T18:49:00.847 に答える
4

2つの方法には重要な違いがあります。を使用して、への参照hello(String)変更しようとしていることと、参照を指定して、オブジェクトのメンバーを変更するために参照を使用していることです。Stringhello(CustomObject)

hello(String)への参照を取りますString。関数では、参照が指すオブジェクトを変更しようとしていますが、参照の値渡しコピーのみを変更しています。したがって、変更はメソッドの外部に反映されません。

hello(CustomObject)オブジェクトへの参照のコピーが与えられ、それを使用して実際のオブジェクトを変更できます。これは、オブジェクトの内容を変更することと考えてください。したがって、変更発信者に反映されます。

オブジェクトへの参照が与えられると、公開されたメソッド/フィールドを使用してオブジェクトを変更できます

于 2012-08-03T18:47:27.393 に答える
0

t新しいオブジェクトを指し、スコープはメソッドのみであるため、変更は外部に表示されません。

2番目のケースでは、変更する値がオブジェクトに更新されるため、これらの変更はメソッド呼び出し後に表示されます。

于 2012-08-03T18:47:22.490 に答える
0

文字列の場合は、ローカルパラメータ参照を変更しているだけだからです。

于 2012-08-03T18:49:10.807 に答える
0

Stringは不変オブジェクトであるため、機能しません

于 2016-06-01T20:47:12.163 に答える