0

関数fermatFactorization()では、クラスを使用しabいるため、参照パラメーターとして渡されます。Longただし、関数でandにtestFermatFactorization()渡すaと、 andの値は変更されないため、 が出力されます。これを印刷してテストしたところ、期待どおりの出力が得られました。bfermatFactorization()abtestFermatFactorization()(0)(0)abfermatFactorization()

私は何を見落としていますか?に割り当てられているだけなので、コンパイラはaandbを変更できfermatFactorization()ますか?(疑わしい)

public static void fermatFactorization(Long n, Long a, Long b)   
//PRE:  n is the integer to be factored
//POST: a and b will be the factors of n
{
    Long v = 1L;
    Long x = ((Double)Math.ceil(Math.sqrt(n))).longValue();
    //System.out.println("x: " + x);
    Long u = 2*x + 1;
    Long r = x*x - n;

    while(r != 0)                 //we are looking for the condition x^2 - y^2 - n to be zero
    {
        while(r>0)
        {
            r = r - v;            //update our condition
            v = v + 2;            //v keeps track of (y+1)^2 - y^2 = 2y+1, increase the "y"
        }
        while(r<0)
        {
            r = r + u;
            u = u + 2;            //keeps track of (x+1)^2 - x^2 = 2x+1, increases the "x"
        }
    }

    a = (u + v - 2)/2;            //remember what u and v equal; --> (2x+1 + 2y+1 - 2)/2 = x+y
    b = (u - v)/2;                //                             --> (2x+1 -(2y+1))/2 = x-y
}

public static void testFermatFactorization(Long number)
{
    Long a = 0L;
    Long b = 0L;
    fermatFactorization(number, a, b);
    System.out.printf("Fermat Factorization(%d) = (%d)(%d)\n", number, a, b);
}
4

4 に答える 4

8

Javaは値渡しです。引数に新しい値を割り当てても、呼び出し元のメソッドの値には影響しません。

2つのオプションがあります。

  • メソッドを戻りab-int[]または2つのフィールドを持つ別FactorizationRezultのクラスを使用します。そうすれば、パラメータとしてではなく、呼び出されたメソッドでローカル変数として宣言しますabこれが最も推奨されるアプローチです。

  • 別のアプローチは、MutableLongを使用してメソッドを使用するsetValue(..)ことです。これにより、変更が呼び出し元のメソッドのオブジェクトに影響します。これはあまりお勧めできません

于 2012-10-02T21:15:06.770 に答える
3

aとbは参照であり、「参照パラメーター」ではなく、値によって渡されます。呼び出されたメソッドで値が変更されますが、呼び出し元には影響しません。

Javaには「参照渡し」はありません。

于 2012-10-02T21:17:13.683 に答える
1

Javaでは、すべてが値によって渡されます。参照による呼び出しはありません。オブジェクトを渡す場合でも、その参照は値によって渡されます。したがって、Longオブジェクトを渡すときは、オブジェクトへの参照を値で渡すだけです。

Long、他のプリミティブ型ラッパーと同様に、「不変」です。内部にある長い値を変更することはできません。したがって、デザインを変更したくない場合は、長い間変更可能なラッパーを作成して(または使用してMutableLong)、それを渡す必要があります。メソッドの引数を変更する代わりに、結果を返すように設計を変更する方が、私に言わせればはるかに良い方法です。

于 2012-10-02T21:19:46.540 に答える
0

=演算子を使用すると、ローカル変数が格納されているメモリ内のスポットがクリアされ、置き換えられます。これは元の変数には影響しません。値渡しでは、実際の参照ではなく、オブジェクト内のデータを変更することのみが可能です(フィールド内のフィールドの変更など)。

于 2012-10-02T21:15:17.273 に答える