001/** 002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.jboot.utils; 017 018import com.jfinal.kit.LogKit; 019 020import java.lang.reflect.Field; 021import java.lang.reflect.InvocationTargetException; 022import java.lang.reflect.Method; 023import java.util.Arrays; 024import java.util.LinkedList; 025import java.util.List; 026import java.util.function.Predicate; 027 028/** 029 * 反射相关操作的工具类 030 */ 031public class ReflectUtil { 032 033 public static <T> T getStaticFieldValue(Class<?> dClass, String fieldName) { 034 return getFieldValue(dClass, fieldName, null); 035 } 036 037 public static <T> T getFieldValue(Object getFrom, String fieldName) { 038 return getFieldValue(getFrom.getClass(), fieldName, getFrom); 039 } 040 041 private static <T> T getFieldValue(Class<?> dClass, String fieldName, Object getFrom) { 042 try { 043 if (StrUtil.isBlank(fieldName)) { 044 throw new IllegalArgumentException("fieldName must not be null or empty."); 045 } 046 Field field = searchField(dClass, f -> f.getName().equals(fieldName)); 047 if (field == null) { 048 throw new NoSuchFieldException(fieldName); 049 } 050 051 return getFileValue(getFrom, field); 052 053 } catch (NoSuchFieldException e) { 054 throw new RuntimeException(e); 055 } 056 } 057 058 private static <T> T getFileValue(Object getFrom, Field field) { 059 boolean accessible = field.isAccessible(); 060 try { 061 field.setAccessible(true); 062 return (T) field.get(getFrom); 063 } catch (IllegalAccessException e) { 064 LogKit.error(e.toString(), e); 065 } finally { 066 field.setAccessible(accessible); 067 } 068 return null; 069 } 070 071 072 public static void setStaticFieldValue(Class<?> dClass, String fieldName, Object value) { 073 setFieldValue(dClass, null, fieldName, value); 074 } 075 076 077 public static void setFieldValue(Object setTo, String fieldName, Object value) { 078 setFieldValue(setTo.getClass(), setTo, fieldName, value); 079 } 080 081 082 private static void setFieldValue(Class<?> dClass, Object setTo, String fieldName, Object value) { 083 setFieldValue(dClass, setTo, f -> f.getName().equals(fieldName), value); 084 } 085 086 087 private static void setFieldValue(Class<?> dClass, Object setTo, Predicate<Field> filter, Object value) { 088 Field field = searchField(dClass, filter); 089 if (field == null) { 090 throw new IllegalArgumentException("No such field"); 091 } 092 093 setFieldValue(setTo, value, field); 094 } 095 096 public static void setFieldValue(Object setTo, Object value, Field field) { 097 final boolean accessible = field.isAccessible(); 098 try { 099 field.setAccessible(true); 100 field.set(setTo, value); 101 } catch (IllegalAccessException e) { 102 LogKit.error(e.toString(), e); 103 } finally { 104 field.setAccessible(accessible); 105 } 106 } 107 108 109 public static Field searchField(Class<?> dClass, Predicate<Field> filter) { 110 if (dClass == null) { 111 return null; 112 } 113 Field[] fields = dClass.getDeclaredFields(); 114 for (Field field : fields) { 115 if (filter.test(field)) { 116 return field; 117 } 118 } 119 return searchField(dClass.getSuperclass(), filter); 120 } 121 122 123 public static List<Field> searchFieldList(Class<?> dClass, Predicate<Field> filter) { 124 List<Field> fields = new LinkedList<>(); 125 doSearchFieldList(dClass, filter, fields); 126 return fields; 127 } 128 129 130 private static void doSearchFieldList(Class<?> dClass, Predicate<Field> filter, List<Field> searchToList) { 131 if (dClass == null || dClass == Object.class) { 132 return; 133 } 134 135 Field[] fields = dClass.getDeclaredFields(); 136 if (fields.length > 0) { 137 if (filter != null) { 138 for (Field field : fields) { 139 if (filter.test(field)) { 140 searchToList.add(field); 141 } 142 } 143 } else { 144 searchToList.addAll(Arrays.asList(fields)); 145 } 146 } 147 148 doSearchFieldList(dClass.getSuperclass(), filter, searchToList); 149 } 150 151 152 public static Method searchMethod(Class<?> dClass, Predicate<Method> filter) { 153 if (dClass == null) { 154 return null; 155 } 156 Method[] methods = dClass.getDeclaredMethods(); 157 for (Method method : methods) { 158 if (filter.test(method)) { 159 return method; 160 } 161 } 162 return searchMethod(dClass.getSuperclass(), filter); 163 } 164 165 166 public static List<Method> searchMethodList(Class<?> dClass, Predicate<Method> filter) { 167 List<Method> methods = new LinkedList<>(); 168 doSearchMethodList(dClass, filter, methods); 169 return methods; 170 } 171 172 173 private static void doSearchMethodList(Class<?> dClass, Predicate<Method> filter, List<Method> searchToList) { 174 if (dClass == null) { 175 return; 176 } 177 Method[] methods = dClass.getDeclaredMethods(); 178 if (methods.length > 0) { 179 if (filter != null) { 180 for (Method method : methods) { 181 if (filter.test(method)) { 182 searchToList.add(method); 183 } 184 } 185 } else { 186 searchToList.addAll(Arrays.asList(methods)); 187 } 188 } 189 190 doSearchMethodList(dClass.getSuperclass(), filter, searchToList); 191 } 192 193 194 public static <T> T invokeStaticMethod(Class<?> dClass, String methodName, Object... args) { 195 return invokeStaticMethod(dClass, m -> m.getName().equals(methodName), args); 196 } 197 198 199 public static <T> T invokeStaticMethod(Class<?> dClass, Predicate<Method> filter, Object... args) { 200 Method method = searchMethod(dClass, filter); 201 if (method == null) { 202 throw new IllegalArgumentException("No such method."); 203 } 204 return invokeMethod(null, method, args); 205 } 206 207 208 public static <T> T invokeMethod(Object obj, String methodName, Object... args) { 209 return invokeMethod(obj, m -> m.getName().equals(methodName), args); 210 } 211 212 213 public static <T> T invokeMethod(Object obj, Predicate<Method> filter, Object... args) { 214 Method method = searchMethod(obj.getClass(), filter); 215 if (method == null) { 216 throw new IllegalArgumentException("No such method."); 217 } 218 return invokeMethod(obj, method, args); 219 } 220 221 222 public static <T> T invokeMethod(Object obj, Method method, Object... args) { 223 final boolean accessible = method.isAccessible(); 224 try { 225 method.setAccessible(true); 226 return (T) method.invoke(obj, args); 227 } catch (IllegalAccessException | InvocationTargetException e) { 228 LogKit.error(e.toString(), e); 229 } finally { 230 method.setAccessible(accessible); 231 } 232 return null; 233 } 234 235}