This commit is contained in:
Looly
2025-10-04 16:35:13 +08:00
parent 944e914454
commit 745ebacb4d
5 changed files with 88 additions and 35 deletions

View File

@@ -69,7 +69,7 @@ public class BeanUtil {
* @since 3.0.7
*/
public static DynaBean createDynaBean(final Object bean) {
return new DynaBean(bean);
return DynaBean.of(bean);
}
/**
@@ -578,31 +578,7 @@ public class BeanUtil {
return ClassUtil.getClassName(bean, isSimple).equals(isSimple ? StrUtil.upperFirst(beanClassName) : beanClassName);
}
/**
* 编辑Bean的字段static字段不会处理<br>
* 例如需要对指定的字段做判空操作、null转""操作等等。
*
* @param bean bean
* @param editor 编辑器函数
* @param <T> 被编辑的Bean类型
* @return bean
* @since 5.6.4
*/
public static <T> T edit(final T bean, final UnaryOperator<Field> editor) {
if (bean == null) {
return null;
}
final Field[] fields = FieldUtil.getFields(bean.getClass());
for (final Field field : fields) {
if (ModifierUtil.isStatic(field)) {
continue;
}
editor.apply(field);
}
return bean;
}
// region ----- edit
/**
* 把Bean里面的String属性做trim操作。此方法直接对传入的Bean做修改。
* <p>
@@ -634,6 +610,33 @@ public class BeanUtil {
});
}
/**
* 编辑Bean的字段static字段不会处理<br>
* 例如需要对指定的字段做判空操作、null转""操作等等。
*
* @param bean bean
* @param editor 编辑器函数
* @param <T> 被编辑的Bean类型
* @return bean
* @since 5.6.4
*/
public static <T> T edit(final T bean, final UnaryOperator<Field> editor) {
if (bean == null) {
return null;
}
final Field[] fields = FieldUtil.getFields(bean.getClass());
for (final Field field : fields) {
if (ModifierUtil.isStatic(field)) {
continue;
}
editor.apply(field);
}
return bean;
}
// endregion
// region ----- check
/**
* 判断Bean是否为空对象空对象表示本身为{@code null}或者所有属性都为{@code null}<br>
* 此方法不判断static属性
@@ -725,6 +728,7 @@ public class BeanUtil {
return hasSetter(clazz) || hasPublicField(clazz);
}
// endregion
// region ----- hasXXX

View File

@@ -26,6 +26,7 @@ import cn.hutool.v7.core.reflect.ClassUtil;
import cn.hutool.v7.core.reflect.ConstructorUtil;
import cn.hutool.v7.core.reflect.method.MethodUtil;
import java.io.Serial;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
@@ -39,6 +40,7 @@ import java.util.Map;
* @since 3.0.7
*/
public class DynaBean implements Cloneable, Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**

View File

@@ -187,7 +187,8 @@ public class AnnotationUtilTest {
@Test
public void testIsInherited() {
Assertions.assertFalse(AnnotationUtil.isInherited(AnnotationForTest.class));
Assertions.assertTrue(AnnotationUtil.isInherited(AnnotationForTest.class));
Assertions.assertFalse(AnnotationUtil.isInherited(MetaAnnotationForTest.class));
}
@Test

View File

@@ -39,11 +39,14 @@ import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.beans.PropertyDescriptor;
import java.io.Serial;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.*;
@@ -71,17 +74,15 @@ public class BeanUtilTest {
@Test
public void fillBeanTest() {
final Person person = BeanUtil.fillBean(new Person(), new ValueProvider<String>() {
final Person person = BeanUtil.fillBean(new Person(), new ValueProvider<>() {
@Override
public Object value(final String key, final Type valueType) {
switch (key) {
case "name":
return "张三";
case "age":
return 18;
}
return null;
return switch (key) {
case "name" -> "张三";
case "age" -> 18;
default -> null;
};
}
@Override
@@ -686,6 +687,7 @@ public class BeanUtilTest {
@Data
public static class HllFoodEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private String bookId;
@@ -791,6 +793,7 @@ public class BeanUtilTest {
@Data
public static class PrivilegeIClassification implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private String id;
@@ -891,6 +894,7 @@ public class BeanUtilTest {
@Data
public static class Student implements Serializable{
@Serial
private static final long serialVersionUID = 1L;
String name;
@@ -1011,4 +1015,28 @@ public class BeanUtilTest {
final boolean b = BeanUtil.hasGetter(Object.class);
assertFalse(b);
}
@Test
void checkBean_withNullBean_shouldReturnTrue() {
Predicate<Field> predicate = field -> true;
assertTrue(BeanUtil.checkBean(null, predicate));
}
@Test
void checkBean_withNoMatchingFields_shouldReturnFalse() {
Person bean = new Person();
Predicate<Field> predicate = field -> false;
assertFalse(BeanUtil.checkBean(bean, predicate));
}
@Test
void checkBean_withMatchingField_shouldReturnTrue() {
Person bean = new Person();
Predicate<Field> predicate = field -> "name".equals(field.getName());
assertTrue(BeanUtil.checkBean(bean, predicate));
predicate = field -> "age".equals(field.getName());
assertTrue(BeanUtil.checkBean(bean, predicate));
}
}

View File

@@ -20,6 +20,9 @@ import lombok.Data;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link DynaBean}单元测试
*
@@ -27,6 +30,21 @@ import org.junit.jupiter.api.Test;
*/
public class DynaBeanTest {
@Test
void createDynaBean_withNullBean_shouldThrowException() {
assertThrows(IllegalArgumentException.class, () -> BeanUtil.createDynaBean(null));
}
@Test
void createDynaBean_withPlainObject_shouldReturnDynaBean() {
BeanUtilTest.Person bean = new BeanUtilTest.Person();
DynaBean dynaBean = BeanUtil.createDynaBean(bean);
assertNotNull(dynaBean);
assertEquals(bean, dynaBean.getBean());
assertEquals(BeanUtilTest.Person.class, dynaBean.getBeanClass());
}
@Test
public void beanTest() {
final User user = new User();