/** * Licensed under the Apache License, Version 2.0 (the "License"); */ package com.github.quartzweb.utils; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.UndeclaredThrowableException; import java.util.Arrays; import java.util.List; /** * @author quxiucheng [[email protected]] */ public class ReflectionUtils { private static final String SETTER_PREFIX = "set"; private static final String GETTER_PREFIX = "get"; /** * 查找某个字段 * @param clazz * @param name * @param type * @return */ public static Field findField(Class<?> clazz, String name, Class<?> type) { Class<?> searchType = clazz; while (!Object.class.equals(searchType) && searchType != null) { Field[] fields = searchType.getDeclaredFields(); for (Field field : fields) { if ((name == null || name.equals(field.getName())) && (type == null || type.equals(field.getType()))) { return field; } } searchType = searchType.getSuperclass(); } return null; } public static Object getField(Field field, Object target) { try { return field.get(target); } catch (IllegalAccessException ex) { throw new IllegalStateException( "Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage()); } } public static void setField(Field field, Object target, Object value) { try { field.set(target, value); } catch (IllegalAccessException ex) { throw new IllegalStateException( "Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage()); } } /** * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数. */ public static Object getField(final Object obj, final String fieldName) { Field field = getAccessibleField(obj, fieldName); if (field == null) { throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]"); } Object result = null; try { result = field.get(obj); } catch (IllegalAccessException e) { rethrowRuntimeException(e); } return result; } /** * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数. */ public static void setField(final Object obj, final String fieldName, final Object value) { Field field = getAccessibleField(obj, fieldName); if (field == null) { throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]"); } try { field.set(obj, value); } catch (IllegalAccessException e) { rethrowRuntimeException(e); } } public static Method findMethod(Class<?> clazz, String name, Class<?>... paramTypes) { while (clazz != null) { Method[] methods = (clazz.isInterface() ? clazz.getMethods() : getDeclaredMethods(clazz)); for (Method method : methods) { if (name.equals(method.getName()) && (paramTypes == null || Arrays.equals(paramTypes, method.getParameterTypes()))) { return method; } } clazz = clazz.getSuperclass(); } return null; } public static void getAllDeclaredMethods(Class<?> clazz, List<Method> methodList) { Method[] methods = getDeclaredMethods(clazz); for (Method method : methods) { methodList.add(method); } if (clazz.getSuperclass() != null) { getAllDeclaredMethods(clazz.getSuperclass(), methodList); } else if (clazz.isInterface()) { for (Class<?> superIfc : clazz.getInterfaces()) { getAllDeclaredMethods(superIfc, methodList); } } } private static Method[] getDeclaredMethods(Class<?> clazz) { return clazz.getDeclaredMethods(); } public static Object invokeMethod(Method method, Object target, Object... args) { try { return method.invoke(target, args); } catch (Exception ex) { handleReflectionException(ex); } throw new IllegalStateException("Should never get here"); } public static void makeAccessible(Field field) { if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) { field.setAccessible(true); } } /** * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. * * 如向上转型到Object仍无法找到, 返回null. */ public static Field getAccessibleField(final Object obj, final String fieldName) { for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) { try { Field field = superClass.getDeclaredField(fieldName); makeAccessible(field); return field; } catch (NoSuchFieldException e) {//NOSONAR // Field不在当前类定义,继续向上转型 continue;// new add } } return null; } public static void makeAccessible(Method method) { if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) && !method.isAccessible()) { method.setAccessible(true); } } public static void makeAccessible(Constructor<?> ctor) { if ((!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(ctor.getDeclaringClass().getModifiers())) && !ctor.isAccessible()) { ctor.setAccessible(true); } } public static void handleReflectionException(Exception ex) { if (ex instanceof NoSuchMethodException) { throw new IllegalStateException("Method not found: " + ex.getMessage()); } if (ex instanceof IllegalAccessException) { throw new IllegalStateException("Could not access method: " + ex.getMessage()); } if (ex instanceof InvocationTargetException) { handleInvocationTargetException((InvocationTargetException) ex); } if (ex instanceof RuntimeException) { throw (RuntimeException) ex; } throw new UndeclaredThrowableException(ex); } public static void handleInvocationTargetException(InvocationTargetException ex) { rethrowRuntimeException(ex.getTargetException()); } public static void rethrowRuntimeException(Throwable ex) { if (ex instanceof RuntimeException) { throw (RuntimeException) ex; } if (ex instanceof Error) { throw (Error) ex; } throw new UndeclaredThrowableException(ex); } }