Java按引用传递和编译器优化

Java按引用传递和编译器优化,java,function,reference,parameter-passing,Java,Function,Reference,Parameter Passing,在函数FermatFactoriation中,a和b作为引用参数传递,因为我使用的是Long类。但是,在函数TestFermatFactoriation中,当我将a和b传递给FermatFactoriation时,a和b的值不会改变,因此TestFermatFactoriation打印00。我通过在费马分解中打印出a和b来测试这一点,得到了预期的输出 我忽略了什么?编译器能否在费马因式分解中改变a和b,因为它们只被分配给?值得怀疑 public static void fermatFactori

在函数FermatFactoriation中,a和b作为引用参数传递,因为我使用的是Long类。但是,在函数TestFermatFactoriation中,当我将a和b传递给FermatFactoriation时,a和b的值不会改变,因此TestFermatFactoriation打印00。我通过在费马分解中打印出a和b来测试这一点,得到了预期的输出

我忽略了什么?编译器能否在费马因式分解中改变a和b,因为它们只被分配给?值得怀疑

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);
}

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

您有两个选择:

使您的方法返回a和b-在int[]中或使用具有两个字段的单独FactoriationRezult类。这样,您将在被调用的方法中将a和b声明为局部变量,而不是将它们作为参数。这是最可取的办法

另一种方法是使用MutableLong和setValue。。方法-这样更改将影响调用方方法中的对象。这是不可取的


使用=运算符清除内存中存储局部变量的位置并替换它。这不会影响原始变量。“按值传递”仅允许您修改对象中的数据,就像修改其中的字段一样,而不是它的实际引用。

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


Java中没有“按引用传递”。

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


与其他基本类型包装器一样,Long是不可变的。您无法更改其内部的long值。所以,如果你不想改变你的设计,你必须自己制作一个可变的长包装,或者使用可变的长包装并传递它。如果你问我,改变你的设计以返回结果而不是改变方法参数是一个更好的方法。

看看这个关于改变包装类的问题:看看我的答案。它实际上不是通过引用,而是通过引用的值,所以你不能像更改指针那样更改原始引用。如果性能很重要,你应该使用long而不是long,如果可以的话,也应该使用double而不是double。我真的很喜欢Java,我从来都不知道这一点。。。真可惜