From 8efcf8eda76e4bd5a58a6e0bb5773a63d8ca654a Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 28 Jan 2025 01:34:27 +0800 Subject: [PATCH] fix bug --- .../core/annotation/AnnotationUtil.java | 24 +++++++++++ .../dromara/hutool/core/bean/PropDesc.java | 42 +++++++++++-------- .../hutool/core/bean/SimpleBeanDesc.java | 1 - 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/annotation/AnnotationUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/annotation/AnnotationUtil.java index 21eac96a9..2984485d2 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/annotation/AnnotationUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/annotation/AnnotationUtil.java @@ -166,6 +166,30 @@ public class AnnotationUtil { return (null == annotationEle) ? null : toCombination(annotationEle).getAnnotation(annotationType); } + /** + * 检查是否包含指定注解
+ * 注解类传入全名,通过{@link Class#forName(String)}加载,避免不存在的注解导致的ClassNotFoundException + * + * @param annotationEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission + * @param annotationTypeName 注解类型完整类名 + * @return 是否包含指定注解 + * @since 6.0.0 + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + public static boolean hasAnnotation(final AnnotatedElement annotationEle, final String annotationTypeName) { + Class aClass = null; + try { + // issue#IB0JP5,Android可能无这个类 + aClass = Class.forName(annotationTypeName); + } catch (final ClassNotFoundException e) { + // ignore + } + if(null != aClass){ + return hasAnnotation(annotationEle, aClass); + } + return false; + } + /** * 检查是否包含指定注解 * diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/PropDesc.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/PropDesc.java index eca676bf3..410014299 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/PropDesc.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/PropDesc.java @@ -22,7 +22,6 @@ import org.dromara.hutool.core.convert.ConvertUtil; import org.dromara.hutool.core.reflect.*; import org.dromara.hutool.core.reflect.method.MethodInvoker; -import java.beans.Transient; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; @@ -34,6 +33,11 @@ import java.lang.reflect.Type; */ public class PropDesc { + /** + * Transient注解的类名 + */ + private static final String TRANSIENT_CLASS_NAME = "java.beans.Transient"; + /** * 字段 */ @@ -73,9 +77,21 @@ public class PropDesc { * @param setterMethod set方法 */ public PropDesc(final String fieldName, final Method getterMethod, final Method setterMethod) { + this(fieldName, MethodInvoker.of(getterMethod), MethodInvoker.of(setterMethod)); + } + + /** + * 构造
+ * Getter和Setter方法设置为默认可访问 + * + * @param fieldName 字段名 + * @param getter get方法执行器 + * @param setter set方法执行器 + */ + public PropDesc(final String fieldName, final Invoker getter, final Invoker setter){ this.fieldName = fieldName; - this.getter = null == getterMethod ? null : MethodInvoker.of(getterMethod); - this.setter = null == setterMethod ? null : MethodInvoker.of(setterMethod); + this.getter = getter; + this.setter = setter; } /** @@ -190,7 +206,7 @@ public class PropDesc { /** * 获取属性值
- * 首先调用字段对应的Getter方法获取值,如果Getter方法不存在,则判断字段如果为public,则直接获取字段值
+ * 首先调用字段对应的Getter方法获取值,如果Getter方法不存在,则直接获取字段值
* 此方法不检查任何注解,使用前需调用 {@link #isReadable(boolean)} 检查是否可读 * * @param bean Bean对象 @@ -216,7 +232,7 @@ public class PropDesc { /** * 获取属性值,自动转换属性值类型
- * 首先调用字段对应的Getter方法获取值,如果Getter方法不存在,则判断字段如果为public,则直接获取字段值 + * 首先调用字段对应的Getter方法获取值,如果Getter方法不存在,则直接获取字段值 * * @param bean Bean对象 * @param targetType 返回属性值需要转换的类型,null表示不转换 @@ -269,7 +285,7 @@ public class PropDesc { /** * 设置Bean的字段值
- * 首先调用字段对应的Setter方法,如果Setter方法不存在,则判断字段如果为public,则直接赋值字段值
+ * 首先调用字段对应的Setter方法,如果Setter方法不存在,则直接赋值字段值
* 此方法不检查任何注解,使用前需调用 {@link #isWritable(boolean)} 检查是否可写 * * @param bean Bean对象 @@ -432,7 +448,6 @@ public class PropDesc { * @param getterMethod 读取方法,可为{@code null} * @return 是否为Transient关键字修饰的 */ - @SuppressWarnings({"rawtypes", "unchecked"}) private static boolean isTransientForGet(final Field field, final Method getterMethod) { boolean isTransient = ModifierUtil.hasAny(field, ModifierType.TRANSIENT); @@ -442,16 +457,7 @@ public class PropDesc { // 检查注解 if (!isTransient) { - Class aClass = null; - try { - // issue#IB0JP5,Android可能无这个类 - aClass = Class.forName("java.beans.Transient"); - } catch (final ClassNotFoundException e) { - // ignore - } - if(null != aClass){ - isTransient = AnnotationUtil.hasAnnotation(getterMethod, aClass); - } + isTransient = AnnotationUtil.hasAnnotation(getterMethod, TRANSIENT_CLASS_NAME); } } @@ -474,7 +480,7 @@ public class PropDesc { // 检查注解 if (!isTransient) { - isTransient = AnnotationUtil.hasAnnotation(setterMethod, Transient.class); + isTransient = AnnotationUtil.hasAnnotation(setterMethod, TRANSIENT_CLASS_NAME); } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/SimpleBeanDesc.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/SimpleBeanDesc.java index 338327805..3f0ee6614 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/SimpleBeanDesc.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/SimpleBeanDesc.java @@ -17,7 +17,6 @@ package org.dromara.hutool.core.bean; import org.dromara.hutool.core.bean.path.AbstractBeanDesc; -import org.dromara.hutool.core.reflect.TypeUtil; import org.dromara.hutool.core.reflect.method.MethodInvoker; import org.dromara.hutool.core.reflect.method.MethodNameUtil; import org.dromara.hutool.core.reflect.method.MethodUtil;