I'm still learning Java, and I've been reading articles on several sites. I found an article at Java Code Geeks that I have a question about. The article is explaining open/closed principle. The article uses a scenario of applying a discount to a company's product for it's example. The first part of the code is as follows:
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Discount {
public BigDecimal apply(BigDecimal price) {
BigDecimal percent = new BigDecimal("0.10");
BigDecimal discount = price.multiply(percent);
return price.subtract(discount.setScale(2, RoundingMode.HALF_UP));
}
}
The second part of the code is as follows:
import java.math.BigDecimal;
public class DiscountService {
public BigDecimal applyDiscounts(BigDecimal price,Discount discount) {
BigDecimal discountPrice = price.add(BigDecimal.ZERO);
discountPrice = discount.apply(discountPrice);
return discountPrice;
}
}
On Oracle's site, it says that the ZERO in BigDecimal has a a value of 0 and a scale of zero. Does this mean that in price.add(BigDecimal.ZERO)
we are simply adding 0 to the price that's brought in? If so, why? Or is it there simply to drop the decimal places from the price? Or is there some other purpose for it?
Thanks!
price. add(BigDecimal. ZERO) is being used to create a new BigDecimal since BigDecimal doesn't have a copy constructor. As to why, this is presumably a defensive copy in case the BigDecimal being passed in is actually a "sabotaged" version (because BigDecimal isn't final ) whose value can be changed after the fact.
BigDecimal. add(BigDecimal augend, MathContext mc) returns a BigDecimal whose value is (this + augend), with rounding according to the MathContext settings. If either number is zero and the precision setting is nonzero then the other number, rounded if necessary, is used as the result.
BigDecimal BD2 = new BigDecimal("0.0000"); Apparently, the BD2 object's value is zero, although we've constructed it by a string with a scale of four. As we all know, 0.0000 is the same as 0 in value.
So there is no difference between BigDecimal.ZERO and new BigDecimal ("0") from the point of view of how they are used, except that creating a new instance is more work for the JVM (and will generate more garbage when you don't need that object any more).
Two BigDecimal objects that are equal in value but have a different scale (like 2.0 and 2.00) are considered equal by this method. Therefore, we can check BigDecimal.ZERO.compareTo (givenBdNumber) == 0 to decide if givenBdNumber has the value zero. Next, let's test if this method can correctly tell if both BigDecimal objects BD1 and BD2 are zero:
Let us apply the following operations on BigDecimal using the in-built methods in Java −. Addition: add() method Subtraction: subtract() method Multiplication: multiply() method Division: divide() method.
The BigDeicmal class provides the signum method to tell if the given BigDecimal object's value is negative (-1), zero (0), or positive (1). The signum method will ignore the scale attribute.
price.add(BigDecimal.ZERO)
is being used to create a new BigDecimal
since BigDecimal
doesn't have a copy constructor.
As to why, this is presumably a defensive copy in case the BigDecimal
being passed in is actually a "sabotaged" version (because BigDecimal
isn't final
) whose value can be changed after the fact. This is talked about in depth in Effective Java as the item "Make defensive copies when needed;" Item 39 in 2nd edition or Item 50 in 3rd Edition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With