Hutool Hutool
(opens new window)
🏡首页
📖指南
🎢最佳实践
💖支持
💡javaDoc (opens new window)
⏳更新记录 (opens new window)
  • 🍎gitee (opens new window)
  • 🍏github (opens new window)
(opens new window)
🏡首页
📖指南
🎢最佳实践
💖支持
💡javaDoc (opens new window)
⏳更新记录 (opens new window)
  • 🍎gitee (opens new window)
  • 🍏github (opens new window)
  • 快速入门

  • 核心(hutool-core)

    • AI(Hutool-ai)

    • 注解(annotation)

    • 数组(array)

    • JavaBean(bean)

    • 缓存(cache)

    • 类加载器(classloader)

    • 编码解码(codec)

    • 集合(collection)

    • 比较器(comparator)

    • 压缩(compress)

    • 类型转换(convert)

    • 数据(data)

    • 日期时间(date)

    • 异常(exception)

    • 函数(func)

    • IO流(io)

    • 语言特性(lang)

    • Map(map)

    • 数字数学(math)

    • 网络(net)

    • 对象池(pool)

    • 反射(reflect)

      • 反射
      • 类工具-ClassUtil
      • 反射工具-ReflectUtil
      • 字段工具-FieldUtil
      • 构造器工具-ConstructorUtil
      • 类型工具-TypeUtil
      • ClassScanner 类扫描器
      • JDK代理工具-JdkProxyUtil
      • 修饰符工具-ModifierUtil
        • 1. 功能概述
        • 2. 核心功能
          • 2.1 修饰符组合判断
          • 2.2 具体修饰符判断
          • 2.3 修饰符操作
        • 3. 方法详解
          • 3.1 修饰符组合判断
          • hasAny(clazz, modifierTypes)
          • hasAny(member, modifierTypes)
          • hasAll(clazz, modifierTypes)
          • hasAll(member, modifierTypes)
          • 3.2 具体修饰符判断
          • isDefault(method)
          • isPublic(member)
          • isPublic(clazz)
          • isStatic(member)
          • isSynthetic(member)
          • isAbstract(clazz)
          • 3.3 修饰符操作
          • removeFinalModify(field)
        • 4. 示例代码
          • 4.1 修饰符判断示例
          • 4.2 组合修饰符判断示例
          • 4.3 移除 final 修饰符示例
        • 5. 注意事项
        • 6. 最佳实践
      • 类描述工具-ClassDescUtil
    • 正则(regex)

    • 服务提供(spi)

    • 聚合操作(stream)

    • 字符串文本(text)

    • 并发和线程(thread)

    • 树结构(tree)

    • 工具集合(util)

    • XML操作(xml)

  • 定时任务(hutool-cron)

  • 加密(hutool-crypto)

  • 数据库(hutool-db)

  • 扩展(hutool-extra)

  • HTTP(hutool-http)

  • 日志(hutool-log)

  • 配置文件(hutool-setting)

  • JSON(hutool-json)

  • Office办公(hutool-poi)

  • 套接字(hutool-socket)

  • GUI(hutool-swing)

  • 指南
  • 核心(hutool-core)
  • 反射(reflect)
Hutool
2026-01-24
目录

修饰符工具-ModifierUtil

# 1. 功能概述

ModifierUtil 是 Hutool 提供的修饰符工具类,用于处理 Java 反射中的修饰符信息。该工具类封装了对类、字段、方法和构造函数修饰符的检查和操作功能,提供了便捷的方法来判断各种修饰符,以及修改字段的修饰符。

# 2. 核心功能

# 2.1 修饰符组合判断

  • hasAny(clazz, modifierTypes):判断类是否存在给定修饰符中的任意一个
  • hasAny(member, modifierTypes):判断成员是否存在给定修饰符中的任意一个
  • hasAny(modifiers, checkedModifiers):判断修饰符中是否存在给定修饰符中的任意一个
  • hasAll(clazz, modifierTypes):判断类中是否同时存在所有给定修饰符
  • hasAll(member, modifierTypes):判断成员中是否同时存在所有给定修饰符
  • hasAll(modifiers, checkedModifiers):判断修饰符中是否同时存在所有给定修饰符

# 2.2 具体修饰符判断

  • isDefault(method):判断方法是否为 default 方法
  • isPublic(member):判断是否为 public 成员(构造、字段、方法)
  • isPublic(clazz):判断是否为 public 类
  • isPrivate(member):判断是否为 private 成员(构造、字段、方法)
  • isPrivate(clazz):判断是否为 private 类
  • isStatic(member):判断是否为 static 成员(构造、字段、方法)
  • isStatic(clazz):判断是否为 static 类
  • isSynthetic(member):判断是否为合成成员(由编译器生成)
  • isSynthetic(clazz):判断是否为合成类(由编译器生成)
  • isAbstract(member):判断是否为抽象成员
  • isAbstract(clazz):判断是否为抽象类
  • isInterface(clazz):判断是否为接口

# 2.3 修饰符操作

  • removeFinalModify(field):移除字段的 final 修饰符,使其可修改

# 3. 方法详解

# 3.1 修饰符组合判断

# hasAny(clazz, modifierTypes)

功能:判断类是否存在给定修饰符中的任意一个

参数:

  • clazz:类,如果为 null 返回 false
  • modifierTypes:修饰符枚举,如果为空返回 false

返回值:是否有指定修饰符,如果有返回 true,否则 false

示例:

// 判断 String 类是否有 public 或 final 修饰符
boolean hasModifier = ModifierUtil.hasAny(String.class, ModifierType.PUBLIC, ModifierType.FINAL); // 返回 true

# hasAny(member, modifierTypes)

功能:判断成员是否存在给定修饰符中的任意一个

参数:

  • member:构造、字段或方法,如果为 null 返回 false
  • modifierTypes:修饰符枚举,如果为空返回 false

返回值:是否有指定修饰符,如果有返回 true,否则 false

示例:

Field field = String.class.getDeclaredField("value");
// 判断字段是否有 private 或 final 修饰符
boolean hasModifier = ModifierUtil.hasAny(field, ModifierType.PRIVATE, ModifierType.FINAL); // 返回 true

# hasAll(clazz, modifierTypes)

功能:判断类中是否同时存在所有给定修饰符

参数:

  • clazz:类,如果为 null 返回 false
  • modifierTypes:修饰符枚举,如果为空返回 false

返回值:是否同时存在所有指定修饰符,如果有返回 true,否则 false

示例:

// 判断 String 类是否同时有 public 和 final 修饰符
boolean hasAllModifiers = ModifierUtil.hasAll(String.class, ModifierType.PUBLIC, ModifierType.FINAL); // 返回 true

# hasAll(member, modifierTypes)

功能:判断成员中是否同时存在所有给定修饰符

参数:

  • member:构造、字段或方法,如果为 null 返回 false
  • modifierTypes:修饰符枚举,如果为空返回 false

返回值:是否同时存在所有指定修饰符,如果有返回 true,否则 false

示例:

Field field = String.class.getDeclaredField("value");
// 判断字段是否同时有 private 和 final 修饰符
boolean hasAllModifiers = ModifierUtil.hasAll(field, ModifierType.PRIVATE, ModifierType.FINAL); // 返回 true

# 3.2 具体修饰符判断

# isDefault(method)

功能:判断方法是否为 default 方法

参数:

  • method:方法,如果为 null 返回 false

返回值:是否为 default 方法

示例:

// 定义接口
interface MyInterface {
    default void defaultMethod() {
        // 默认方法实现
    }
}

Method method = MyInterface.class.getDeclaredMethod("defaultMethod");
boolean isDefault = ModifierUtil.isDefault(method); // 返回 true

# isPublic(member)

功能:判断是否为 public 成员

参数:

  • member:构造、字段或方法,如果为 null 返回 false

返回值:是否是 public

示例:

Method method = String.class.getDeclaredMethod("length");
boolean isPublic = ModifierUtil.isPublic(method); // 返回 true

# isPublic(clazz)

功能:判断是否为 public 类

参数:

  • clazz:类,如果为 null 返回 false

返回值:是否是 public

示例:

boolean isPublic = ModifierUtil.isPublic(String.class); // 返回 true
boolean isPrivate = ModifierUtil.isPublic(Class.forName("java.lang.StringBuilder$StringBuilderAccessor")); // 返回 false

# isStatic(member)

功能:判断是否为 static 成员

参数:

  • member:构造、字段或方法,如果为 null 返回 false

返回值:是否是 static

示例:

Field field = Math.class.getDeclaredField("PI");
boolean isStatic = ModifierUtil.isStatic(field); // 返回 true

# isSynthetic(member)

功能:判断是否为合成成员(由 java 编译器生成的)

参数:

  • member:构造、字段或方法

返回值:是否是合成成员

示例:

// 合成成员通常由编译器生成,如内部类访问外部类的私有成员时生成的桥接方法

# isAbstract(clazz)

功能:判断是否为抽象类

参数:

  • clazz:类,如果为 null 返回 false

返回值:是否是抽象类

示例:

boolean isAbstract = ModifierUtil.isAbstract(AbstractList.class); // 返回 true

# 3.3 修饰符操作

# removeFinalModify(field)

功能:移除字段的 final 修饰符,使其可修改

参数:

  • field:被修改的 field,不可以为空

异常:

  • HutoolException:包装 IllegalAccessException 等异常

说明:

  • 并非所有 final 字段都可以修改,以下类型的字段无法通过反射修改(编译器内联优化):
    • 基本类型:byte, char, short, int, long, float, double, boolean
    • Literal String 类型(直接双引号字符串)
  • 以下类型的字段可以通过反射修改:
    • 基本类型的包装类:Byte、Character、Short、Long、Float、Double、Boolean
    • 字符串,通过 new String("") 实例化
    • 自定义 Java 类

示例:

// 定义类
class FinalTest {
    public static final List<String> LIST = new ArrayList<>();
    public static final String LITERAL_STRING = "literal";
    public static final String NEW_STRING = new String("new string");
}

// 修改非字面量字符串
Field newStringField = FinalTest.class.getDeclaredField("NEW_STRING");
ModifierUtil.removeFinalModify(newStringField);
newStringField.set(null, new String("modified"));
Console.log(FinalTest.NEW_STRING); // 输出:modified

// 修改集合
Field listField = FinalTest.class.getDeclaredField("LIST");
ModifierUtil.removeFinalModify(listField);
List<String> newList = new ArrayList<>();
newList.add("item1");
newList.add("item2");
listField.set(null, newList);
Console.log(FinalTest.LIST); // 输出:[item1, item2]

# 4. 示例代码

# 4.1 修饰符判断示例

// 判断类修饰符
Console.log("String 类是否为 public:{}", ModifierUtil.isPublic(String.class)); // true
Console.log("String 类是否为 final:{}", ModifierUtil.hasAny(String.class, ModifierType.FINAL)); // true
Console.log("String 类是否为抽象类:{}", ModifierUtil.isAbstract(String.class)); // false
Console.log("AbstractList 类是否为抽象类:{}", ModifierUtil.isAbstract(AbstractList.class)); // true

// 判断方法修饰符
Method lengthMethod = String.class.getDeclaredMethod("length");
Console.log("String.length() 是否为 public:{}", ModifierUtil.isPublic(lengthMethod)); // true
Console.log("String.length() 是否为 static:{}", ModifierUtil.isStatic(lengthMethod)); // false

// 判断字段修饰符
Field valueField = String.class.getDeclaredField("value");
Console.log("String.value 是否为 private:{}", ModifierUtil.isPrivate(valueField)); // true
Console.log("String.value 是否为 final:{}", ModifierUtil.hasAny(valueField, ModifierType.FINAL)); // true

// 判断构造方法修饰符
Constructor<?> constructor = String.class.getDeclaredConstructor(String.class);
Console.log("String(String) 构造方法是否为 public:{}", ModifierUtil.isPublic(constructor)); // true

# 4.2 组合修饰符判断示例

// 定义测试类
class TestClass {
    public static final int PUBLIC_STATIC_FINAL = 1;
    private int privateField;
    protected static void protectedStaticMethod() {}
    public abstract void abstractMethod();
}

// 获取字段和方法
Field publicStaticFinalField = TestClass.class.getDeclaredField("PUBLIC_STATIC_FINAL");
Field privateField = TestClass.class.getDeclaredField("privateField");
Method protectedStaticMethod = TestClass.class.getDeclaredMethod("protectedStaticMethod");

// 组合修饰符判断
Console.log("PUBLIC_STATIC_FINAL 是否同时有 public、static、final:{}",
    ModifierUtil.hasAll(publicStaticFinalField, ModifierType.PUBLIC, ModifierType.STATIC, ModifierType.FINAL)); // true

Console.log("PUBLIC_STATIC_FINAL 是否有 private 或 protected:{}",
    ModifierUtil.hasAny(publicStaticFinalField, ModifierType.PRIVATE, ModifierType.PROTECTED)); // false

Console.log("privateField 是否有 private 或 static:{}",
    ModifierUtil.hasAny(privateField, ModifierType.PRIVATE, ModifierType.STATIC)); // true

Console.log("protectedStaticMethod 是否同时有 protected 和 static:{}",
    ModifierUtil.hasAll(protectedStaticMethod, ModifierType.PROTECTED, ModifierType.STATIC)); // true

# 4.3 移除 final 修饰符示例

// 定义包含 final 字段的类
class FinalFieldClass {
    // 字面量字符串,无法修改
    public static final String LITERAL = "literal";
    // 通过 new 创建的字符串,可以修改
    public static final String DYNAMIC = new String("dynamic");
    // 集合类型,可以修改
    public static final Map<String, String> MAP = new HashMap<>();
}

// 尝试修改字面量字符串(无法修改)
Field literalField = FinalFieldClass.class.getDeclaredField("LITERAL");
ModifierUtil.removeFinalModify(literalField);
literalField.set(null, "modified_literal");
Console.log("字面量字符串修改后:{}", FinalFieldClass.LITERAL); // 输出:literal(未被修改)

// 修改动态字符串(可以修改)
Field dynamicField = FinalFieldClass.class.getDeclaredField("DYNAMIC");
ModifierUtil.removeFinalModify(dynamicField);
dynamicField.set(null, new String("modified_dynamic"));
Console.log("动态字符串修改后:{}", FinalFieldClass.DYNAMIC); // 输出:modified_dynamic

// 修改集合(可以修改)
Field mapField = FinalFieldClass.class.getDeclaredField("MAP");
ModifierUtil.removeFinalModify(mapField);
Map<String, String> newMap = new HashMap<>();
newMap.put("key", "value");
mapField.set(null, newMap);
Console.log("集合修改后:{}", FinalFieldClass.MAP); // 输出:{key=value}

# 5. 注意事项

  1. 空指针安全:所有方法都进行了空指针检查,避免了空指针异常
  2. 修饰符枚举:使用 ModifierType 枚举来表示修饰符,提高了代码的可读性和类型安全性
  3. 合成成员:合成成员是由编译器生成的,通常用于实现内部类访问外部类私有成员等功能
  4. final 修饰符移除限制:并非所有 final 字段都可以通过反射修改,字面量基本类型和字符串无法修改
  5. JDK 版本限制:在 JDK 9+ 中,removeFinalModify 方法可能抛出 NoSuchFieldException 异常,原因是模块外无法访问某些属性
  6. 性能考虑:修饰符判断方法直接调用 JDK 反射 API,性能较好;而 removeFinalModify 方法涉及反射操作,性能开销较大

# 6. 最佳实践

  1. 修饰符判断:在反射操作中,经常需要判断类、字段或方法的修饰符,使用 ModifierUtil 可以简化代码
  2. 动态修改 final 字段:在测试或特殊场景下,可能需要修改 final 字段的值,使用 removeFinalModify 方法可以实现
  3. 组合修饰符检查:使用 hasAny 和 hasAll 方法可以方便地检查多个修饰符
  4. 注意 final 字段修改限制:在修改 final 字段前,了解该字段是否可以被修改,避免无效操作
  5. 性能优化:对于频繁调用的修饰符判断,考虑缓存结果
  6. 结合其他反射工具:与 ClassUtil、FieldUtil、ReflectUtil 等工具结合使用,实现更复杂的反射操作

ModifierUtil 工具类简化了 Java 反射中修饰符的处理,提供了便捷的方法来判断和操作修饰符。无论是在框架开发还是日常编程中,该工具类都能帮助开发者更高效地处理反射相关的修饰符操作。

JDK代理工具-JdkProxyUtil
类描述工具-ClassDescUtil

← JDK代理工具-JdkProxyUtil 类描述工具-ClassDescUtil→

Theme by Vdoing | Copyright © 2025-2026 Hutool | Apache-2.0
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式