BigDecimal加法在函数中给出0

时间:2015-05-29 20:57:57

标签: java

我有以下Junit

private void calculatePF(BigDecimal leftPF,
        BigDecimal rightPF) {
    rightPF = rightPF.add(new BigDecimal(10));
    leftPF = leftPF.add(new BigDecimal(10));
}

@Test
public void autoPlaceUser() throws Exception{
    BigDecimal leftPF = BigDecimal.ZERO;
    BigDecimal rightPF = BigDecimal.ZERO;
    calculatePF(leftPF, rightPF);
    System.out.println("rightPF : "+rightPF);
    System.out.println("leftPF : "+leftPF);

}

即使我执行了添加并将其分配给变量,我仍然不明白为什么值仍然为零。我在这里想念的是什么?

5 个答案:

答案 0 :(得分:4)

BigDecimal 不可变。在重新分配这些变量之前,您分配给leftPFrightPF的值不会更改。

如果您希望从calculatePF获得可观察到的副作用,请将您的BigDecimal传递给数组,如下所示:

private void calculatePF(BigDecimal[] pf) {
    pf[1] = pf[1].add(new BigDecimal(10));
    pf[0] = pf[0].add(new BigDecimal(10));
}
@Test
public void autoPlaceUser() throws Exception{
    BigDecimal pf[] = new BigDecimal[] {
        BigDecimal.ZERO, BigDecimal.ZERO
    };
    calculatePF(pf);
    System.out.println("rightPF : "+pf[1]);
    System.out.println("leftPF : "+pf[1]);
}

答案 1 :(得分:2)

这里发生了一些事情:

  • BigDecimal是不可变的。当您对其执行操作时,它会返回 BigDecimal实例。
  • Java 按值传递leftPF内的rightPFcalculatePF是原始参考文献的副本
  • 您无法在Java中重置引用。当您通过rightPF重新分配rightPF = rightPF.add(new BigDecimal(10));时,您需要更改本地 rightPF的值,而不是autoPlaceUser中的值。那仍然指向原始的rightPF。这同样适用于leftPF

那你在这做什么?您必须将实例分配给原始 rightPFleftPF。有很多方法可以做到这一点:

  • rightPFleftPF创建单独的方法,然后执行rightPF = calcRightPF(rightPF)
  • 简单地进行内联;它不是很多代码,所以可以在线完成。
  • rightPFleftPF封装在另一个对象中。然后你甚至不必退货;你可以在你的方法中设置rightPFleftPF对象本身(使用setter)。
  • BigDecimal[]leftPF使用数组(rightPF),并将新实例分配给相应的下标。你不必在这里返回数组,因为你直接修改它(参见dasblinkenlight' s answer)。这类似于将其封装在对象中,但您只需在此处使用数组。

答案 2 :(得分:1)

Java 按值传递:在添加数字的方法中重新分配BigDecimal变量rightPF时,调用者传递的原始变量方法保持不变。

要解决此问题,您需要返回新值。一种方法是让方法返回包含新值的BigDecimal数组:

private BigDecimal[] calculatePF(BigDecimal leftPF,
        BigDecimal rightPF) {
    rightPF = rightPF.add(new BigDecimal(10));
    leftPF = leftPF.add(new BigDecimal(10));
    return new BigDecimal[] {leftPF, rightPF};
}

public void autoPlaceUser() throws Exception{
    BigDecimal leftPF = BigDecimal.ZERO;
    BigDecimal rightPF = BigDecimal.ZERO;
    BigDecimal[] newPF = calculatePF(leftPF, rightPF);
    System.out.println("rightPF : " + newPF[1]);
    System.out.println("leftPF : " + newPF[0]);

}

答案 3 :(得分:0)

您只是将新值分配给函数calculatePF中的变量。打印的实际值永远不会改变。

答案 4 :(得分:0)

您有一个范围问题。

calculatePf()方法中的leftPf和rightPf变量的范围限定在该方法内。

autoPlaceUser()方法中的leftPf和rightPf变量的范围限定在该方法内。

它们是两组完全不同的变量。