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 8cb40558c..317025495 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 @@ -433,11 +433,11 @@ public class PropDesc { * @return 是否为Transient关键字修饰的 */ private static boolean isTransientForGet(final Field field, final Method getterMethod) { - boolean isTransient = ModifierUtil.hasModifier(field, ModifierType.TRANSIENT); + boolean isTransient = ModifierUtil.hasAny(field, ModifierType.TRANSIENT); // 检查Getter方法 if (!isTransient && null != getterMethod) { - isTransient = ModifierUtil.hasModifier(getterMethod, ModifierType.TRANSIENT); + isTransient = ModifierUtil.hasAny(getterMethod, ModifierType.TRANSIENT); // 检查注解 if (!isTransient) { @@ -456,11 +456,11 @@ public class PropDesc { * @return 是否为Transient关键字修饰的 */ private static boolean isTransientForSet(final Field field, final Method setterMethod) { - boolean isTransient = ModifierUtil.hasModifier(field, ModifierType.TRANSIENT); + boolean isTransient = ModifierUtil.hasAny(field, ModifierType.TRANSIENT); // 检查Getter方法 if (!isTransient && null != setterMethod) { - isTransient = ModifierUtil.hasModifier(setterMethod, ModifierType.TRANSIENT); + isTransient = ModifierUtil.hasAny(setterMethod, ModifierType.TRANSIENT); // 检查注解 if (!isTransient) { diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ClassMember.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ClassMember.java new file mode 100644 index 000000000..51afb2f15 --- /dev/null +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ClassMember.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2024 Hutool Team and hutool.cn + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.dromara.hutool.core.reflect; + +import org.dromara.hutool.core.lang.Assert; + +import java.lang.reflect.Member; + +/** + * 类成员,用于获取类的修饰符等,如: + *
+ *     ClassMember member = new ClassMember(String.class);
+ *     Console.log(member.getModifiers());
+ * 
+ * + * @author looly + * @since 6.0.0 + */ +public class ClassMember implements Member { + + /** + * 静态工厂方法,用于创建ClassMember对象 + * + * @param clazz 类 + * @return ClassMember对象 + */ + public static ClassMember of(final Class clazz) { + return new ClassMember(clazz); + } + + private final Class clazz; + + /** + * 构造 + * + * @param clazz 类 + */ + public ClassMember(final Class clazz) { + this.clazz = Assert.notNull(clazz); + } + + @Override + public Class getDeclaringClass() { + return this.clazz; + } + + @Override + public String getName() { + return this.clazz.getName(); + } + + @Override + public int getModifiers() { + return this.clazz.getModifiers(); + } + + @Override + public boolean isSynthetic() { + return this.clazz.isSynthetic(); + } +} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ModifierUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ModifierUtil.java index 21a921a0d..eebb9246f 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ModifierUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/ModifierUtil.java @@ -32,28 +32,42 @@ import java.lang.reflect.Modifier; */ public class ModifierUtil { + // region ----- hasAny + /** - * 是否同时存在一个或多个修饰符(可能有多个修饰符,如果有指定的修饰符则返回true) + * 类是否存在给定修饰符中的任意一个
+ * 如定义修饰符为:{@code public static final},那么如果传入的modifierTypes为: + * * * @param clazz 类,如果为{@code null}返回{@code false} * @param modifierTypes 修饰符枚举,如果为空返回{@code false} * @return 是否有指定修饰符,如果有返回true,否则false,如果提供参数为null返回false */ - public static boolean hasModifier(final Class clazz, final ModifierType... modifierTypes) { + public static boolean hasAny(final Class clazz, final ModifierType... modifierTypes) { if (null == clazz || ArrayUtil.isEmpty(modifierTypes)) { return false; } - return 0 != (clazz.getModifiers() & ModifierType.orToInt(modifierTypes)); + return hasAny(ClassMember.of(clazz), modifierTypes); } /** - * 是否同时存在一个或多个修饰符(可能有多个修饰符,如果有指定的修饰符则返回true) + * 成员是否存在给定修饰符中的任意一个
+ * 如定义修饰符为:{@code public static final},那么如果传入的modifierTypes为: + * * * @param member 构造、字段或方法,如果为{@code null}返回{@code false} * @param modifierTypes 修饰符枚举,如果为空返回{@code false} * @return 是否有指定修饰符,如果有返回true,否则false,如果提供参数为null返回false */ - public static boolean hasModifier(final Member member, final ModifierType... modifierTypes) { + public static boolean hasAny(final Member member, final ModifierType... modifierTypes) { if (null == member || ArrayUtil.isEmpty(modifierTypes)) { return false; } @@ -61,33 +75,92 @@ public class ModifierUtil { } /** - * 是否同时存在一个或多个修饰符(可能有多个修饰符,如果有指定的修饰符则返回true) + * 需要检查的修饰符中是否存在给定修饰符中的任意一个
+ * 如定义修饰符为:{@code public static final},那么如果传入的modifierTypes为: + * * * @param modifiers 类、构造、字段或方法的修饰符 * @param checkedModifiers 需要检查的修饰符,如果为空返回{@code false} * @return 是否有指定修饰符,如果有返回true,否则false,如果提供参数为null返回false */ - public static boolean hasModifier(final int modifiers, final int... checkedModifiers) { - if(ArrayUtil.isEmpty(checkedModifiers)){ + public static boolean hasAny(final int modifiers, final int... checkedModifiers) { + if (ArrayUtil.isEmpty(checkedModifiers)) { return false; } return 0 != (modifiers & ModifierType.orToInt(checkedModifiers)); } + // endregion + + // region ----- hasAll /** - * 是否同时存在一个或多个修饰符(可能有多个修饰符,如果有指定的修饰符则返回true) + * 类中是否同时存在所有给定修饰符
+ * 如定义修饰符为:{@code public static final},那么如果传入的modifierTypes为: + * + * + * @param clazz 类,如果为{@code null}返回{@code false} + * @param modifierTypes 修饰符枚举,如果为空返回{@code false} + * @return 是否同时存在所有指定修饰符,如果有返回true,否则false,如果提供参数为null返回false + */ + public static boolean hasAll(final Class clazz, final ModifierType... modifierTypes) { + if (null == clazz || ArrayUtil.isEmpty(modifierTypes)) { + return false; + } + return hasAll(ClassMember.of(clazz), modifierTypes); + } + + /** + * 成员中是否同时存在所有给定修饰符
+ * 如定义修饰符为:{@code public static final},那么如果传入的modifierTypes为: + * + * + * @param member 构造、字段或方法,如果为{@code null}返回{@code false} + * @param modifierTypes 修饰符枚举,如果为空返回{@code false} + * @return 是否同时存在所有指定修饰符,如果有返回true,否则false,如果提供参数为null返回false + */ + public static boolean hasAll(final Member member, final ModifierType... modifierTypes) { + if (null == member || ArrayUtil.isEmpty(modifierTypes)) { + return false; + } + final int checkedModifiersInt = ModifierType.orToInt(modifierTypes); + return checkedModifiersInt == (member.getModifiers() & checkedModifiersInt); + } + + /** + * 需要检查的修饰符中是否同时存在所有给定修饰符
+ * 如定义修饰符为:{@code public static final},那么如果传入的checkedModifiers为: + * * * @param modifiers 类、构造、字段或方法的修饰符 * @param checkedModifiers 需要检查的修饰符,如果为空返回{@code false} - * @return 是否有指定修饰符,如果有返回true,否则false,如果提供参数为null返回false + * @return 是否同时存在所有指定修饰符,如果有返回true,否则false,如果提供参数为null返回false */ - public static boolean hasAllModifier(final int modifiers, final int... checkedModifiers) { - if(ArrayUtil.isEmpty(checkedModifiers)){ + public static boolean hasAll(final int modifiers, final int... checkedModifiers) { + if (ArrayUtil.isEmpty(checkedModifiers)) { return false; } final int checkedModifiersInt = ModifierType.orToInt(checkedModifiers); return checkedModifiersInt == (modifiers & checkedModifiersInt); } + // endregion + + // region ----- isXXX /** * 提供的方法是否为default方法 @@ -215,6 +288,7 @@ public class ModifierUtil { public static boolean isInterface(final Class clazz) { return null != clazz && clazz.isInterface(); } + // endregion /** * 设置final的field字段可以被修改 @@ -248,7 +322,7 @@ public class ModifierUtil { * @since 5.8.8 */ public static void removeFinalModify(final Field field) { - if (!hasModifier(field, ModifierType.FINAL)) { + if (!hasAny(field, ModifierType.FINAL)) { return; } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/method/MethodMatcherUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/method/MethodMatcherUtil.java index 9eab7e89f..40096c1a0 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/reflect/method/MethodMatcherUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/reflect/method/MethodMatcherUtil.java @@ -112,7 +112,7 @@ public class MethodMatcherUtil { * @return 方法匹配器 */ public static Predicate forModifiers(final int... modifiers) { - return method -> ModifierUtil.hasAllModifier(method.getModifiers(), modifiers); + return method -> ModifierUtil.hasAll(method.getModifiers(), modifiers); } // endregion diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/util/ModifierUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/util/ModifierUtilTest.java index 2909e5c99..34a10b180 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/util/ModifierUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/util/ModifierUtilTest.java @@ -31,13 +31,53 @@ import java.util.List; public class ModifierUtilTest { @Test - public void hasModifierTest() throws NoSuchMethodException { + public void hasAnyTest() throws NoSuchMethodException { final Method method = ModifierUtilTest.class.getDeclaredMethod("ddd"); - Assertions.assertTrue(ModifierUtil.hasModifier(method, ModifierType.PRIVATE)); - Assertions.assertTrue(ModifierUtil.hasModifier(method, - ModifierType.PRIVATE, - ModifierType.STATIC) + Assertions.assertTrue(ModifierUtil.hasAny(method, + ModifierType.PRIVATE)); + Assertions.assertTrue(ModifierUtil.hasAny(method, + ModifierType.PRIVATE, + ModifierType.STATIC) ); + Assertions.assertTrue(ModifierUtil.hasAny(method, + ModifierType.PRIVATE, + ModifierType.ABSTRACT) + ); + } + + @Test + public void hasAllTest() throws NoSuchMethodException { + final Method method = ModifierUtilTest.class.getDeclaredMethod("ddd"); + Assertions.assertTrue(ModifierUtil.hasAll(method, + ModifierType.PRIVATE)); + Assertions.assertTrue(ModifierUtil.hasAll(method, + ModifierType.PRIVATE, + ModifierType.STATIC) + ); + Assertions.assertFalse(ModifierUtil.hasAll(method, + ModifierType.PRIVATE, + // 不存在 + ModifierType.ABSTRACT) + ); + } + + @Test + void issueIAQ2U0Test() throws NoSuchMethodException { + final Method method = ModifierUtilTest.class.getDeclaredMethod("ddd"); + + Assertions.assertTrue(ModifierUtil.hasAny(method, + ModifierType.PRIVATE, + ModifierType.STATIC, + // 不存在 + ModifierType.TRANSIENT + )); + + Assertions.assertFalse(ModifierUtil.hasAll(method, + ModifierType.PRIVATE, + ModifierType.STATIC, + // 不存在 + ModifierType.TRANSIENT + )); } private static void ddd() { @@ -56,12 +96,12 @@ public class ModifierUtilTest { public void setFinalFieldValueTest() { final String fieldName = "DIALECTS"; final List dialects = - Arrays.asList( - 1, - 2, - 3, - 99 - ); + Arrays.asList( + 1, + 2, + 3, + 99 + ); final Field field = FieldUtil.getField(JdbcDialects.class, fieldName); ModifierUtil.removeFinalModify(field); FieldUtil.setFieldValue(JdbcDialects.class, fieldName, dialects); @@ -72,6 +112,6 @@ public class ModifierUtilTest { @SuppressWarnings("unused") public static class JdbcDialects { private static final List DIALECTS = - Arrays.asList(1L, 2L, 3L); + Arrays.asList(1L, 2L, 3L); } }