在函数fermatFactorization()
中,a
和b
作为参考参数传递,因为我使用的是Long
类。但是,当我将testFermatFactorization()
和a
传递给b
时,在功能fermatFactorization()
中,a
和b
的值不会更改,并且所以testFermatFactorization()
打印(0)(0)
。我通过在a
中打印出b
和fermatFactorization()
对此进行了测试,得到了我预期的输出。
我在俯瞰什么?编译器是否可以更改a
中的b
和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);
}
答案 0 :(得分:8)
Java是按值传递的。如果为参数指定新值,则不会影响调用方法中的值。
您有两种选择:
让您的方法返回a
和b
- 在int[]
中或使用具有两个字段的单独FactorizationRezult
类。这样,您将在被调用方法中将a
和b
声明为局部变量,而不是将它们作为参数。这是最明智的方法。
另一种方法是使用MutableLong
并使用setValue(..)
方法 - 这样更改将影响调用方法中的对象。这是不太明智的
答案 1 :(得分:3)
a和b是引用,而不是'引用参数',它们按值传递。在被调用的方法中更改了值,但这对调用者没有影响。
Java中没有“通过引用传递”。
答案 2 :(得分:1)
在Java中,一切都按值传递。没有按引用的方式调用。即使传递一个Object,它的引用也是按值传递的。因此,当您传递Long
对象时,您只是按值传递对它的引用。
Long
是“不可变的”。你不能改变里面的长值。所以,如果你不想改变你的设计,你必须自己制作一个可变的包装器(或使用MutableLong
)并传递它。如果你问我,更改设计以返回结果而不是更改方法参数是一种更好的方法。
答案 3 :(得分:0)
使用=运算符清除存储局部变量的内存中的位置并替换它。这将不影响原始变量。按值传递只允许您修改对象中的数据(比如修改其中的字段),而不是它的实际参考。