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为:
+ *
+ * - public、static 返回{@code true}
+ * - public、abstract返回{@code true}
+ * - private、abstract返回{@code false}
+ *
*
* @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为:
+ *
+ * - public、static 返回{@code true}
+ * - public、abstract返回{@code true}
+ * - private、abstract返回{@code false}
+ *
*
* @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为:
+ *
+ * - public、static 返回{@code true}
+ * - public、abstract返回{@code true}
+ * - private、abstract返回{@code false}
+ *
*
* @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为:
+ *
+ * - public、static 返回{@code true}
+ * - public、abstract返回{@code false}
+ * - private、abstract返回{@code false}
+ *
+ *
+ * @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为:
+ *
+ * - public、static 返回{@code true}
+ * - public、abstract返回{@code false}
+ * - private、abstract返回{@code false}
+ *
+ *
+ * @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为:
+ *
+ * - public、static 返回{@code true}
+ * - public、abstract返回{@code false}
+ * - private、abstract返回{@code false}
+ *
*
* @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);
}
}