修复Money类的setAmount方法没有获取当前币种的小数位数而是使用的默认小数位和在遇到非2小数位的币种(如日元使用 0 位)会导致金额设置错误问题(pr#3970@Github)

This commit is contained in:
Looly 2025-06-20 11:05:57 +08:00
parent aaa6932ae1
commit 39f51ee899
3 changed files with 65 additions and 14 deletions

View File

@ -312,7 +312,7 @@ public class Money implements Serializable, Comparable<Money> {
*/
public void setAmount(final BigDecimal amount) {
if (amount != null) {
cent = rounding(amount.movePointRight(2), DEFAULT_ROUNDING_MODE);
cent = rounding(amount.movePointRight(currency.getDefaultFractionDigits()), DEFAULT_ROUNDING_MODE);
}
}

View File

@ -16,24 +16,35 @@
package cn.hutool.v7.core.math;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import java.util.Currency;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class MoneyTest {
@Test
public void yuanToCentTest() {
final Money money = new Money("1234.56");
Assertions.assertEquals(123456, money.getCent());
assertEquals(123456, money.getCent());
Assertions.assertEquals(123456, MathUtil.yuanToCent(1234.56));
assertEquals(123456, MathUtil.yuanToCent(1234.56));
}
@Test
public void centToYuanTest() {
final Money money = new Money(1234, 56);
Assertions.assertEquals(1234.56D, money.getAmount().doubleValue(), 0);
assertEquals(1234.56D, money.getAmount().doubleValue(), 0);
Assertions.assertEquals(1234.56D, MathUtil.centToYuan(123456), 0);
assertEquals(1234.56D, MathUtil.centToYuan(123456), 0);
}
@Test
public void currencyScalingTest() {
Money jpyMoney = new Money(0, Currency.getInstance("JPY"));
jpyMoney.setAmount(BigDecimal.ONE);
assertEquals(1, jpyMoney.getCent());
}
}

View File

@ -16,11 +16,22 @@
package cn.hutool.v7.core.reflect;
import cn.hutool.v7.core.collection.CollUtil;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.FieldNameConstants;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class FieldUtilTest {
@Test
@ -33,15 +44,22 @@ public class FieldUtilTest {
@Test
public void getFieldsTest() {
// 能够获取到父类字段
final Field[] fields = FieldUtil.getFields(ReflectTestBeans.TestSubClass.class);
Assertions.assertEquals(4, fields.length);
Field[] fields = FieldUtil.getFields(ReflectTestBeans.TestSubClass.class);
assertEquals(4, fields.length);
// 如果子类与父类中存在同名字段则这两个字段同时存在子类字段在前父类字段在后
fields = FieldUtil.getFields(TestSubUser.class);
assertEquals(4, fields.length);
List<Field> idFieldList = Arrays.stream(fields).filter(f -> Objects.equals(f.getName(), TestSubUser.Fields.id)).collect(Collectors.toList());
Field firstIdField = CollUtil.getFirst(idFieldList);
assertEquals(Objects.requireNonNull(firstIdField).getDeclaringClass().getName(), TestSubUser.class.getName());
}
@Test
public void setFieldTest() {
final ReflectTestBeans.AClass testClass = new ReflectTestBeans.AClass();
FieldUtil.setFieldValue(testClass, "a", "111");
Assertions.assertEquals(111, testClass.getA());
assertEquals(111, testClass.getA());
}
@Test
@ -64,9 +82,9 @@ public class FieldUtilTest {
testBean.setB(1);
final Object[] fieldsValue = FieldUtil.getFieldsValue(testBean);
Assertions.assertEquals(2, fieldsValue.length);
Assertions.assertEquals("A", fieldsValue[0]);
Assertions.assertEquals(1, fieldsValue[1]);
assertEquals(2, fieldsValue.length);
assertEquals("A", fieldsValue[0]);
assertEquals(1, fieldsValue[1]);
}
@Test
@ -76,8 +94,16 @@ public class FieldUtilTest {
testBean.setB(1);
final Object[] fieldsValue = FieldUtil.getFieldsValue(testBean, (field -> field.getName().equals("a")));
Assertions.assertEquals(1, fieldsValue.length);
Assertions.assertEquals("A", fieldsValue[0]);
assertEquals(1, fieldsValue.length);
assertEquals("A", fieldsValue[0]);
}
@Test
public void getFieldMapTest() {
// 获取指定类中字段名和字段对应的有序Map包括其父类中的字段
// 如果子类与父类中存在同名字段则后者覆盖前者
Map<String, Field> fieldMap = FieldUtil.getFieldMap(TestSubUser.class);
assertEquals(3, fieldMap.size());
}
@Data
@ -85,4 +111,18 @@ public class FieldUtilTest {
private String a;
private int b;
}
@Data
static class TestBaseEntity {
private Long id;
private String remark;
}
@Data
@FieldNameConstants
@EqualsAndHashCode(callSuper = true)
static class TestSubUser extends TestBaseEntity {
private Long id;
private String name;
}
}