Java通过引用传递和编译器优化

时间:2012-10-02 21:13:33

标签: java function reference parameter-passing

在函数fermatFactorization()中,ab作为参考参数传递,因为我使用的是Long类。但是,当我将testFermatFactorization()a传递给b时,在功能fermatFactorization()中,ab的值不会更改,并且所以testFermatFactorization()打印(0)(0)。我通过在a中打印出bfermatFactorization()对此进行了测试,得到了我预期的输出。

我在俯瞰什么?编译器是否可以更改a中的bfermatFactorization(),因为它们只被分配给?(可疑)

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 个答案:

答案 0 :(得分:8)

Java是按值传递的。如果为参数指定新值,则不会影响调用方法中的值。

您有两种选择:

  • 让您的方法返回ab - 在int[]中或使用具有两个字段的单独FactorizationRezult类。这样,您将在被调用方法中将ab声明为局部变量,而不是将它们作为参数。这是最明智的方法。

  • 另一种方法是使用MutableLong并使用setValue(..)方法 - 这样更改将影响调用方法中的对象。这是不太明智的

答案 1 :(得分:3)

a和b是引用,而不是'引用参数',它们按值传递。在被调用的方法中更改了值,但这对调用者没有影响。

Java中没有“通过引用传递”。

答案 2 :(得分:1)

在Java中,一切都按值传递。没有按引用的方式调用。即使传递一个Object,它的引用也是按值传递的。因此,当您传递Long对象时,您只是按值传递对它的引用。

与其他原始类型包装器一样,

Long是“不可变的”。你不能改变里面的长值。所以,如果你不想改变你的设计,你必须自己制作一个可变的包装器(或使用MutableLong)并传递它。如果你问我,更改设计以返回结果而不是更改方法参数是一种更好的方法。

答案 3 :(得分:0)

使用=运算符清除存储局部变量的内存中的位置并替换它。这将影响原始变量。按值传递只允许您修改对象中的数据(比如修改其中的字段),而不是它的实际参考。

相关问题