1 package com.irtimaled.bbor.common;
3 import java.lang.reflect.Constructor;
4 import java.lang.reflect.Field;
5 import java.lang.reflect.ParameterizedType;
6 import java.lang.reflect.Type;
7 import java.util.function.BiFunction;
8 import java.util.function.Function;
10 public class ReflectionHelper {
11 public static <T, R> Function<T, R> getPrivateFieldGetter(Class<?> clazz, Type fieldType, Type... genericTypeArguments) {
12 Field field = getGenericField(clazz, fieldType, genericTypeArguments);
13 if (field == null) return obj -> null;
15 field.setAccessible(true);
18 return (R) field.get(obj);
19 } catch (IllegalAccessException ignored) {
25 public static Field getGenericField(Class<?> clazz, Type fieldType, Type[] genericTypeArguments) {
26 Field field = findField(clazz, fieldType, genericTypeArguments);
27 return field != null ? field : findField(clazz, fieldType, null);
30 private static Field findField(Class<?> clazz, Type fieldType, Type[] genericTypeArguments) {
31 for (Field field : clazz.getDeclaredFields()) {
32 Type type = field.getGenericType();
33 ParameterizedType genericType = TypeHelper.as(type, ParameterizedType.class);
34 if (genericType == null) {
35 if (type != fieldType || genericTypeArguments.length > 0) continue;
39 Type rawType = genericType.getRawType();
40 if (rawType != fieldType) continue;
42 if (genericTypeArguments == null) return field;
44 Type[] actualTypeArguments = genericType.getActualTypeArguments();
45 if (!typesMatch(genericTypeArguments, actualTypeArguments)) continue;
52 private static boolean typesMatch(Type[] left, Type[] right) {
53 if (left.length != right.length) return false;
55 for (int index = 0; index < right.length; index++) {
56 if (right[index] != left[index]) {
63 public static <T, R, S> BiFunction<T, R, S> getPrivateInstanceBuilder(Class<S> clazz, Class<T> parameter1, Class<R> parameter2) {
64 Constructor<S> constructor = findConstructor(clazz, parameter1, parameter2);
65 if (constructor == null) return (obj1, obj2) -> null;
67 constructor.setAccessible(true);
68 return (obj1, obj2) -> {
70 return (S) constructor.newInstance(obj1, obj2);
71 } catch (Exception ignored) {
77 private static <T> Constructor<T> findConstructor(Class<T> clazz, Class<?>... parameters) {
79 return clazz.getDeclaredConstructor(parameters);
80 } catch (NoSuchMethodException ignored) {