2

初歩的な質問かもしれませんが、どのキーワードで検索すればよいかわかりません。

次のようなJavaの戻り変数に値を割り当てることは可能ですか:

static int a[] = new int[2];

static int f(int i) {
    return a[i];
}

static void main() {
    f(1) = 0; // <-- this
}

C/C++ では、ポインターを返し、後でそれに値を割り当てることができます。Java は参照を処理するため、上記のコードが機能することを期待しています。ここで重要なJavaの概念が欠けていますか?

4

8 に答える 8

5

参照型であっても、メソッド呼び出しは変数ではありません

ただし、次のようなものは問題ありません。

static MyClass func() {
   return new MyClass();
}

public static void main(String[] args) {
   func().setAttr(null); // change attributes
}
于 2013-01-30T21:58:56.163 に答える
0

OPの質問は

Javaで戻り変数に値を割り当てることは可能ですか?

非常に単純です...(初期化されたint配列ではすべての値が0であるため、証明を示すために10を割り当てることに注意してください)...

static int a[] = new int[2];

static int f(int[] p, int index, int val) {
    return p[index] = val;
}

static void main() {        
    // f(a, 1, 0); use 10 (below) so we can show proof
    f(a, 1, 10);
    // proof
    System.out.println(a[1]);
}

別の例...ばかげていますが、機能します...

static int a[] = new int[2];

static int[] f(int[] p) {
    return p;
}

static void main() {
    f(a)[1] = 10;
}

さらに別の...

static int a[] = new int[2];

static void f(int i, int val) {
    a[i] = val;
    return;
}

static void main() {
    f(1, 10);
}
于 2013-01-30T23:21:06.513 に答える
0

これは不可能ですが (他のコメントを参照)、値を変更できる独自の MutableInteger クラスを作成できます。

public class MutableInteger {
    public int value;
    public MutableInteger(int value) {
        this.value = value;
    }
    public MutableInteger() {
        this(0);
    }
}

static MutableInteger a[] = new MutableInteger[2];
static {
    for (int i=0; i<a.length; i++) {
        a[i] = new MutableInteger();
    }
}

static MutableInteger f(int i) {
    return a[i];
}

static void main() {
    f(1).value = 0; // <-- this
}
于 2013-01-30T21:59:38.710 に答える
0

いいえ。Java には、プリミティブ型 (C++ とほとんど同じように動作する) と参照型しかありません。参照型は、C++ ポインターと C++ 参照の混合のように動作します。これらは、 を使用すると自動的に逆参照.されます=が、参照されるオブジェクトの値ではなく、参照が指すものを常に変更します。

于 2013-01-30T22:00:34.857 に答える
0

これは機能しません。「マシン」レベルで何が起こるかを理解するのに役立つかもしれません。メソッド内でf、式a[i]は値に評価されintます。この int 値は、その値に関連付けられた配列への接続なしで返されます。メソッドから戻るintと、Java 仮想マシンのオペランド スタックに値があり (中間値と考えてください)、それを使って何かを実行できます。ドロップすることも (1 行で記述した場合に発生します) f(1);、変数 ( int x = f(1)) に代入することもできます。

于 2013-01-30T22:00:53.447 に答える
0

1 つの方法は、配列をMutableInts (またはs) の配列に変換し、その配列の 番目の要素AtomicIntegerへの参照を返すことです。i

static AtomicInteger a[] = new AtomicInteger[2];
static {
    for (int i = 0; i < a.length; ++i) {
        a[i] = new AtomicInteger(0);
    }
}

static AtomicInteger f(int i) {
    return a[i];
}

public static void main(String[] args) {
    f(1).set(0);
}
于 2013-01-30T22:01:01.677 に答える
0

ラムダをこの問題に適用する方法に興味があるかもしれませんが、これは Java 8 プレビューでのみ機能します。

標準ライブラリに次のように定義されたインターフェースがあったとします。

interface Block<T> {
    void accept(T v);
}

(これを に入れるという提案がありますがjava.util.functions、少しだけ複雑にしています...)

これで、次のように例を書くことができます。

// Declare an array
int[] a = new int[5];

// Capture an "assignment reference" to element 2 
Block<Integer> elem2 = v -> a[2] = v;

// Some time later, we want to store a new value in that element:
elem2.accept(360);

そのため、関数は を返しBlock<Integer>、後で呼び出しacceptて格納する値を与えることができます。

于 2013-01-30T23:34:14.717 に答える
0

代入演算子では左側がExpression NameField Access Expression、またはArray Access Expressionのいずれかであるのに対し、f(1)Method Invocation Expressionである必要があるため、これはコンパイル エラーになります。

コンパイル エラーはさておき、これは Java のしくみではありません。Java では、すべてが値渡しされます。特に、この特定の例では、戻り値の型がint.

static /*RETURN TYPE IS PRIMITIVE VALUE:*/ int f(int i) {
    return a[i];
}

中間変数を追加すると、より明確になります。

static /*RETURN TYPE IS PRIMITIVE VALUE:*/ int f(int i) {
    int ret = a[i]; // ret is an independent value from a[i]
                    // it and a[i] can be changed without affecting each other
    return return ret;
}
于 2013-01-30T22:15:13.437 に答える