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

在函数fermatFactorization()ab作为参考参数传递,因为我使用的是Long Class。 但是,在函数testFermatFactorization()当我将ab传递给fermatFactorization()ab的值不会改变,因此testFermatFactorization()打印(0)(0) 。 我通过在fermatFactorization()打印出ab来测试它,我得到了我期望的输出。

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

 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 (2x+1 + 2y+1 - 2)/2 = x+y b = (u - v)/2; // --> (2x+1 -(2y+1))/2 = xy } 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是按值传递的。 如果为参数指定新值,则不会影响调用方法中的值。

你有两个选择:

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

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

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

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

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

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

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