diff --git a/CHANGELOG.md b/CHANGELOG.md index a74e33d8d..dd9f338ca 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ * 【core 】 增加`VersionUtil`版本比较工具(pr#3876@Github) * 【db 】 增加GoldenDB识别(pr#3886@Github) * 【http 】 改进`UrlQuery`对无参URL增加判断识别(issue#IBRVE4@Gitee) +* 【core 】 改进`PropDesc`中去除Transient引用避免NoClassDefFoundError(issue#3901@Github) ### 🐞Bug修复 * 【setting】 修复`SettingLoader`load未抛出异常导致配置文件无法正常遍历的问题(pr#3868@Github) diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java index 6f286ce64..74cc9afb6 100755 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java @@ -192,6 +192,30 @@ public class AnnotationUtil { return null != getAnnotation(annotationEle, annotationType); } + /** + * 检查是否包含指定注解
+ * 注解类传入全名,通过{@link Class#forName(String)}加载,避免不存在的注解导致的ClassNotFoundException + * + * @param annotationEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission + * @param annotationTypeName 注解类型完整类名 + * @return 是否包含指定注解 + * @since 5.8.37 + */ + @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; + } + /** * 获取指定注解默认值
* 如果无指定的属性方法返回null diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/PropDesc.java b/hutool-core/src/main/java/cn/hutool/core/bean/PropDesc.java index 460422a59..811ce70f3 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/PropDesc.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/PropDesc.java @@ -8,7 +8,6 @@ import cn.hutool.core.util.ModifierUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.TypeUtil; -import java.beans.Transient; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; @@ -20,6 +19,11 @@ import java.lang.reflect.Type; */ public class PropDesc { + /** + * Transient注解的类名 + */ + private static final String TRANSIENT_CLASS_NAME = "java.beans.Transient"; + /** * 字段 */ @@ -363,7 +367,6 @@ public class PropDesc { * @return 是否为Transient关键字修饰的 * @since 5.3.11 */ - @SuppressWarnings({"rawtypes", "unchecked"}) private boolean isTransientForGet() { boolean isTransient = ModifierUtil.hasModifier(this.field, ModifierUtil.ModifierType.TRANSIENT); @@ -373,17 +376,7 @@ public class PropDesc { // 检查注解 if (false == isTransient) { - //isTransient = AnnotationUtil.hasAnnotation(this.getter, Transient.class); - Class aClass = null; - try { - // issue#IB0JP5,Android可能无这个类 - aClass = Class.forName("java.beans.Transient"); - } catch (final ClassNotFoundException e) { - // ignore - } - if(null != aClass){ - isTransient = AnnotationUtil.hasAnnotation(this.getter, aClass); - } + isTransient = AnnotationUtil.hasAnnotation(this.getter, TRANSIENT_CLASS_NAME); } } @@ -405,7 +398,7 @@ public class PropDesc { // 检查注解 if (false == isTransient) { - isTransient = AnnotationUtil.hasAnnotation(this.setter, Transient.class); + isTransient = AnnotationUtil.hasAnnotation(this.setter, TRANSIENT_CLASS_NAME); } }