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 * @since 3.0.7
*/ */
public static DynaBean createDynaBean(final Object bean) { 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); return ClassUtil.getClassName(bean, isSimple).equals(isSimple ? StrUtil.upperFirst(beanClassName) : beanClassName);
} }
/** // region ----- edit
* 编辑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;
}
/** /**
* 把Bean里面的String属性做trim操作此方法直接对传入的Bean做修改 * 把Bean里面的String属性做trim操作此方法直接对传入的Bean做修改
* <p> * <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> * 判断Bean是否为空对象空对象表示本身为{@code null}或者所有属性都为{@code null}<br>
* 此方法不判断static属性 * 此方法不判断static属性
@ -725,6 +728,7 @@ public class BeanUtil {
return hasSetter(clazz) || hasPublicField(clazz); return hasSetter(clazz) || hasPublicField(clazz);
} }
// endregion
// region ----- hasXXX // 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.ConstructorUtil;
import cn.hutool.v7.core.reflect.method.MethodUtil; import cn.hutool.v7.core.reflect.method.MethodUtil;
import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -39,6 +40,7 @@ import java.util.Map;
* @since 3.0.7 * @since 3.0.7
*/ */
public class DynaBean implements Cloneable, Serializable { public class DynaBean implements Cloneable, Serializable {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**

View File

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

View File

@ -39,11 +39,14 @@ import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
@ -71,17 +74,15 @@ public class BeanUtilTest {
@Test @Test
public void fillBeanTest() { public void fillBeanTest() {
final Person person = BeanUtil.fillBean(new Person(), new ValueProvider<String>() { final Person person = BeanUtil.fillBean(new Person(), new ValueProvider<>() {
@Override @Override
public Object value(final String key, final Type valueType) { public Object value(final String key, final Type valueType) {
switch (key) { return switch (key) {
case "name": case "name" -> "张三";
return "张三"; case "age" -> 18;
case "age": default -> null;
return 18; };
}
return null;
} }
@Override @Override
@ -686,6 +687,7 @@ public class BeanUtilTest {
@Data @Data
public static class HllFoodEntity implements Serializable { public static class HllFoodEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private String bookId; private String bookId;
@ -791,6 +793,7 @@ public class BeanUtilTest {
@Data @Data
public static class PrivilegeIClassification implements Serializable { public static class PrivilegeIClassification implements Serializable {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private String id; private String id;
@ -891,6 +894,7 @@ public class BeanUtilTest {
@Data @Data
public static class Student implements Serializable{ public static class Student implements Serializable{
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
String name; String name;
@ -1011,4 +1015,28 @@ public class BeanUtilTest {
final boolean b = BeanUtil.hasGetter(Object.class); final boolean b = BeanUtil.hasGetter(Object.class);
assertFalse(b); 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.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
/** /**
* {@link DynaBean}单元测试 * {@link DynaBean}单元测试
* *
@ -27,6 +30,21 @@ import org.junit.jupiter.api.Test;
*/ */
public class DynaBeanTest { 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 @Test
public void beanTest() { public void beanTest() {
final User user = new User(); final User user = new User();