All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.core.util.ModifierUtil Maven / Gradle / Ivy

There is a newer version: 5.8.34
Show newest version
package cn.hutool.core.util;

import cn.hutool.core.exceptions.UtilException;

import java.lang.reflect.*;

/**
 * 修饰符工具类
 *
 * @author looly
 * @since 4.0.5
 */
public class ModifierUtil {

	/**
	 * 修饰符枚举
	 *
	 * @author looly
	 * @since 4.0.5
	 */
	public enum ModifierType {
		/**
		 * public修饰符,所有类都能访问
		 */
		PUBLIC(Modifier.PUBLIC),
		/**
		 * private修饰符,只能被自己访问和修改
		 */
		PRIVATE(Modifier.PRIVATE),
		/**
		 * protected修饰符,自身、子类及同一个包中类可以访问
		 */
		PROTECTED(Modifier.PROTECTED),
		/**
		 * static修饰符,(静态修饰符)指定变量被所有对象共享,即所有实例都可以使用该变量。变量属于这个类
		 */
		STATIC(Modifier.STATIC),
		/**
		 * final修饰符,最终修饰符,指定此变量的值不能变,使用在方法上表示不能被重载
		 */
		FINAL(Modifier.FINAL),
		/**
		 * synchronized,同步修饰符,在多个线程中,该修饰符用于在运行前,对他所属的方法加锁,以防止其他线程的访问,运行结束后解锁。
		 */
		SYNCHRONIZED(Modifier.SYNCHRONIZED),
		/**
		 * (易失修饰符)指定该变量可以同时被几个线程控制和修改
		 */
		VOLATILE(Modifier.VOLATILE),
		/**
		 * (过度修饰符)指定该变量是系统保留,暂无特别作用的临时性变量,序列化时忽略
		 */
		TRANSIENT(Modifier.TRANSIENT),
		/**
		 * native,本地修饰符。指定此方法的方法体是用其他语言在程序外部编写的。
		 */
		NATIVE(Modifier.NATIVE),

		/**
		 * abstract,将一个类声明为抽象类,没有实现的方法,需要子类提供方法实现。
		 */
		ABSTRACT(Modifier.ABSTRACT),
		/**
		 * strictfp,一旦使用了关键字strictfp来声明某个类、接口或者方法时,那么在这个关键字所声明的范围内所有浮点运算都是精确的,符合IEEE-754规范的。
		 */
		STRICT(Modifier.STRICT);

		/**
		 * 修饰符枚举对应的int修饰符值
		 */
		private final int value;

		/**
		 * 构造
		 *
		 * @param modifier 修饰符int表示,见{@link Modifier}
		 */
		ModifierType(int modifier) {
			this.value = modifier;
		}

		/**
		 * 获取修饰符枚举对应的int修饰符值,值见{@link Modifier}
		 *
		 * @return 修饰符枚举对应的int修饰符值
		 */
		public int getValue() {
			return this.value;
		}
	}

	/**
	 * 类是否存在给定修饰符中的任意一个
* 如定义修饰符为:{@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(Class clazz, ModifierType... modifierTypes) { if (null == clazz || ArrayUtil.isEmpty(modifierTypes)) { return false; } return 0 != (clazz.getModifiers() & modifiersToInt(modifierTypes)); } /** * 构造是否存在给定修饰符中的任意一个
* 如定义修饰符为:{@code public static final},那么如果传入的modifierTypes为: *
    *
  • public、static 返回{@code true}
  • *
  • public、abstract返回{@code true}
  • *
  • private、abstract返回{@code false}
  • *
* * @param constructor 构造,如果为{@code null}返回{@code false} * @param modifierTypes 修饰符枚举,如果为空返回{@code false} * @return 是否有指定修饰符,如果有返回true,否则false,如果提供参数为null返回false */ public static boolean hasModifier(Constructor constructor, ModifierType... modifierTypes) { if (null == constructor || ArrayUtil.isEmpty(modifierTypes)) { return false; } return 0 != (constructor.getModifiers() & modifiersToInt(modifierTypes)); } /** * 方法是否存在给定修饰符中的任意一个
* 如定义修饰符为:{@code public static final},那么如果传入的modifierTypes为: *
    *
  • public、static 返回{@code true}
  • *
  • public、abstract返回{@code true}
  • *
  • private、abstract返回{@code false}
  • *
* * @param method 方法,如果为{@code null}返回{@code false} * @param modifierTypes 修饰符枚举,如果为空返回{@code false} * @return 是否有指定修饰符,如果有返回true,否则false,如果提供参数为null返回false */ public static boolean hasModifier(Method method, ModifierType... modifierTypes) { if (null == method || ArrayUtil.isEmpty(modifierTypes)) { return false; } return 0 != (method.getModifiers() & modifiersToInt(modifierTypes)); } /** * 字段是否存在给定修饰符中的任意一个
* 如定义修饰符为:{@code public static final},那么如果传入的modifierTypes为: *
    *
  • public、static 返回{@code true}
  • *
  • public、abstract返回{@code true}
  • *
  • private、abstract返回{@code false}
  • *
* * @param field 构造、字段或方法,如果为{@code null}返回{@code false} * @param modifierTypes 修饰符枚举,如果为空返回{@code false} * @return 是否有指定修饰符,如果有返回true,否则false,如果提供参数为null返回false */ public static boolean hasModifier(Field field, ModifierType... modifierTypes) { if (null == field || ArrayUtil.isEmpty(modifierTypes)) { return false; } return 0 != (field.getModifiers() & modifiersToInt(modifierTypes)); } // region ----- hasAll /** * 类中是否同时存在所有给定修饰符
* 如定义修饰符为:{@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 hasAllModifiers(final Class clazz, final ModifierType... modifierTypes) { if (null == clazz || ArrayUtil.isEmpty(modifierTypes)) { return false; } final int checkedModifiersInt = modifiersToInt(modifierTypes); return checkedModifiersInt == (clazz.getModifiers() & checkedModifiersInt); } /** * 成员中是否同时存在所有给定修饰符
* 如定义修饰符为:{@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 hasAllModifiers(final Member member, final ModifierType... modifierTypes) { if (null == member || ArrayUtil.isEmpty(modifierTypes)) { return false; } final int checkedModifiersInt = modifiersToInt(modifierTypes); return checkedModifiersInt == (member.getModifiers() & checkedModifiersInt); } // endregion /** * 是否是Public字段 * * @param field 字段 * @return 是否是Public */ public static boolean isPublic(Field field) { return hasModifier(field, ModifierType.PUBLIC); } /** * 是否是Public方法 * * @param method 方法 * @return 是否是Public */ public static boolean isPublic(Method method) { return hasModifier(method, ModifierType.PUBLIC); } /** * 是否是Public类 * * @param clazz 类 * @return 是否是Public */ public static boolean isPublic(Class clazz) { return hasModifier(clazz, ModifierType.PUBLIC); } /** * 是否是Public构造 * * @param constructor 构造 * @return 是否是Public */ public static boolean isPublic(Constructor constructor) { return hasModifier(constructor, ModifierType.PUBLIC); } /** * 是否是static字段 * * @param field 字段 * @return 是否是static * @since 4.0.8 */ public static boolean isStatic(Field field) { return hasModifier(field, ModifierType.STATIC); } /** * 是否是static方法 * * @param method 方法 * @return 是否是static * @since 4.0.8 */ public static boolean isStatic(Method method) { return hasModifier(method, ModifierType.STATIC); } /** * 是否是static类 * * @param clazz 类 * @return 是否是static * @since 4.0.8 */ public static boolean isStatic(Class clazz) { return hasModifier(clazz, ModifierType.STATIC); } /** * 是否是合成字段(由java编译器生成的) * * @param field 字段 * @return 是否是合成字段 * @since 5.6.3 */ public static boolean isSynthetic(Field field) { return field.isSynthetic(); } /** * 是否是合成方法(由java编译器生成的) * * @param method 方法 * @return 是否是合成方法 * @since 5.6.3 */ public static boolean isSynthetic(Method method) { return method.isSynthetic(); } /** * 是否是合成类(由java编译器生成的) * * @param clazz 类 * @return 是否是合成 * @since 5.6.3 */ public static boolean isSynthetic(Class clazz) { return clazz.isSynthetic(); } /** * 是否抽象方法 * * @param method 方法 * @return 是否抽象方法 * @since 5.7.23 */ public static boolean isAbstract(Method method) { return hasModifier(method, ModifierType.ABSTRACT); } /** * 设置final的field字段可以被修改 * 只要不会被编译器内联优化的 final 属性就可以通过反射有效的进行修改 -- 修改后代码中可使用到新的值; *

以下属性,编译器会内联优化,无法通过反射修改:

*
    *
  • 基本类型 byte, char, short, int, long, float, double, boolean
  • *
  • Literal String 类型(直接双引号字符串)
  • *
*

以下属性,可以通过反射修改:

*
    *
  • 基本类型的包装类 Byte、Character、Short、Long、Float、Double、Boolean
  • *
  • 字符串,通过 new String("")实例化
  • *
  • 自定义java类
  • *
*
	 * {@code
	 *      //示例,移除final修饰符
	 *      class JdbcDialects {private static final List dialects = new ArrayList<>();}
	 *      Field field = ReflectUtil.getField(JdbcDialects.class, fieldName);
	 * 		ReflectUtil.removeFinalModify(field);
	 * 		ReflectUtil.setFieldValue(JdbcDialects.class, fieldName, dialects);
	 *    }
	 * 
* * @param field 被修改的field,不可以为空 * @throws UtilException IllegalAccessException等异常包装 * @author dazer * @since 5.8.8 */ public static void removeFinalModify(Field field) { if (field != null) { if (hasModifier(field, ModifierUtil.ModifierType.FINAL)) { //将字段的访问权限设为true:即去除private修饰符的影响 if (false == field.isAccessible()) { field.setAccessible(true); } try { //去除final修饰符的影响,将字段设为可修改的 final Field modifiersField = Field.class.getDeclaredField("modifiers"); //Field 的 modifiers 是私有的 modifiersField.setAccessible(true); //& :位与运算符,按位与; 运算规则:两个数都转为二进制,然后从高位开始比较,如果两个数都为1则为1,否则为0。 //~ :位非运算符,按位取反;运算规则:转成二进制,如果位为0,结果是1,如果位为1,结果是0. modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); } catch (final NoSuchFieldException | IllegalAccessException e) { //内部,工具类,基本不抛出异常 throw new UtilException(e, "IllegalAccess for {}.{}", field.getDeclaringClass(), field.getName()); } } } } //-------------------------------------------------------------------------------------------------------- Private method start /** * 多个修饰符做“或”操作,表示同时存在多个修饰符 * * @param modifierTypes 修饰符列表,元素不能为空 * @return “或”之后的修饰符 */ private static int modifiersToInt(ModifierType... modifierTypes) { int modifier = modifierTypes[0].getValue(); for (int i = 1; i < modifierTypes.length; i++) { modifier |= modifierTypes[i].getValue(); } return modifier; } //-------------------------------------------------------------------------------------------------------- Private method end }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy