2012-10-02 41 views
0

在函数fermatFactorization()中,ab正在作为参考参数传递,因为我使用的是Long类。然而,在功能testFermatFactorization()当我通过abfermatFactorization()ab值不得到改变,所以testFermatFactorization()打印(0)(0)。我在fermatFactorization()中打印出ab,并得到了我期望的输出结果。Java通过引用和编译器优化

我在忽略什么?可以在编译器改变abfermatFactorization(),因为它们只被分配到?(可疑)

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

退房有关变异包装类这样的问题: http://stackoverflow.com/questions/4117793/are-java-wrapper-classes-really-immutable – MikeB

+0

看一看我的答案[这里](HTTP: //stackoverflow.com/questions/12591294/how-can-i-delete-an-object-passed-into-a-java-method/12591366#12591366)。它不是通过引用实际引用,而是引用的_value_,所以实际上不能像更改指针那样更改原始引用。 – Brian

+0

如果性能很重要,你应该使用'long'而不是'Long',如果可以的话,也可以使用'double'而不是'Double'。 –

回答

8

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

你有两个选择:

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

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

+0

我真的很喜欢Java,我从来不知道这个......真可惜 – CodeKingPlusPlus

0

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

3

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

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

1

在Java中,所有东西都是按值传递的。没有引用的调用。即使你传递一个对象,它的引用也是按值传递的。所以,当你通过一个Long对象时,你只是简单地将该引用传递给它。

Long,就像其他原始类型包装,是“不可变的”。你不能改变它里面的长整型值。所以,如果你不想改变你的设计,你必须长时间制作一个可变包装(或使用MutableLong)并将其传递。如果你问我,改变你的设计来返回结果而不是改变方法参数是更好的方法。