package cn.mutils.core.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.GenericDeclaration; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import cn.mutils.core.beans.BeanField; /** * Reflection utility of framework */ @SuppressWarnings({"rawtypes", "unchecked", "unused", "UnusedAssignment", "ConstantConditions", "SimplifiableIfStatement"}) public class ReflectUtil { /** * Whether it is assignable from one type to another type */ public static boolean isAssignable(Type one, Type another) { if (one == another) { return true; } if (one == null || another == null) { return false; } if (one.equals(another)) { return true; } if ((one instanceof ParameterizedType) && (another instanceof ParameterizedType)) { ParameterizedType oneParamType = (ParameterizedType) one; ParameterizedType anotherParamType = (ParameterizedType) another; if (!oneParamType.getRawType().equals(anotherParamType.getRawType())) { return false; } Type oneOwner = oneParamType.getOwnerType(); Type anotherOwner = anotherParamType.getOwnerType(); if (oneOwner != null) { if (!oneOwner.equals(anotherOwner)) { return false; } } else { if (anotherOwner != null) { return false; } } return true; } return false; } public static Class<?> getClass(Type type) { if (type.getClass() == Class.class) { return (Class<?>) type; } if (type instanceof ParameterizedType) { return ReflectUtil.getClass(((ParameterizedType) type).getRawType()); } return Object.class; } public static Type getInheritGenericType(Class<?> clazz, TypeVariable<?> typeVariable) { Type type = null; GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration(); do { type = clazz.getGenericSuperclass(); if (type == null) { return null; } if (type instanceof ParameterizedType) { ParameterizedType paramType = (ParameterizedType) type; if (paramType.getRawType() == genericDeclaration) { TypeVariable<?>[] typeVariables = genericDeclaration.getTypeParameters(); Type[] arguments = paramType.getActualTypeArguments(); String typeVariableName = typeVariable.getName(); for (int i = 0, size = typeVariables.length; i < size; i++) { // Fix bug on android VM // It is true while typeVariable==typeVariables[i] on JVM // But It is false on android VM if (typeVariableName.equals(typeVariables[i].getName())) { return arguments[i]; } } return null; } } clazz = ReflectUtil.getClass(type); } while (type != null); return null; } public static boolean isGenericParamType(Type type) { if (type == null) { return false; } if (type instanceof ParameterizedType) { return true; } if (type instanceof Class) { return ReflectUtil.isGenericParamType(((Class<?>) type).getGenericSuperclass()); } return false; } public static Type getGenericParamType(Type type) { if (type instanceof ParameterizedType) { return type; } if (type instanceof Class) { return ReflectUtil.getGenericParamType(((Class<?>) type).getGenericSuperclass()); } return type; } /** * Get TypeVariable generic type information */ public static GenericInfo getGenericInfo(String typeVariableName, Class<?> clazz, ParameterizedType paramType) { GenericInfo gType = new GenericInfo(); int index = -1;// Type parameter index of target class TypeVariable<?>[] typeVariables = clazz.getTypeParameters(); for (int i = 0, size = typeVariables.length; i < size; i++) { if (typeVariableName.equals(typeVariables[i].getName())) { index = i; break; } } if (index != -1) { Type[] args = paramType.getActualTypeArguments(); if (index < args.length) { Type t = paramType.getActualTypeArguments()[index]; if (t instanceof Class) { gType.rawType = (Class<?>) t; } else if (t instanceof ParameterizedType) { gType.rawType = (Class<?>) ((ParameterizedType) t).getRawType(); gType.parameterizedType = t; } } } return gType; } public static <T> Constructor<T> getConstructor(Class<T> targetClass, Class<?>... paramTypes) { try { return targetClass.getConstructor(paramTypes); } catch (Exception e) { return null; } } public static <T> T newInstance(Constructor<T> constructor, Object... args) { try { return constructor.newInstance(args); } catch (Exception e) { return null; } } public static Object get(Object target, BeanField field) { try { return field.get(target); } catch (Exception e) { return null; } } public static void set(Object target, BeanField field, Object value) { try { field.set(target, value); } catch (Exception e) { // IllegalAccessException } } public static Object get(Object target, Field field) { try { if (!field.isAccessible()) { field.setAccessible(true); } return field.get(target); } catch (Exception e) { return null; } } public static void set(Object target, Field field, Object value) { try { if (!field.isAccessible()) { field.setAccessible(true); } field.set(target, value); } catch (Exception e) { // IllegalAccessException } } public static Object invoke(Object target, Method method, Object... args) { try { if (!method.isAccessible()) { method.setAccessible(true); } return method.invoke(target, args); } catch (Exception e) { return null; } } public static Class<?> getParamRawType(Class<?> clazz, Type genericType, int ArgumentIndex) { if (genericType == null) { genericType = clazz.getGenericSuperclass(); } if (!(genericType instanceof ParameterizedType)) { genericType = getGenericParamType(genericType); } if (genericType instanceof ParameterizedType) { Type t = ((ParameterizedType) genericType).getActualTypeArguments()[ArgumentIndex]; if (t instanceof Class) { return (Class<?>) t; } if (t instanceof ParameterizedType) { return (Class<?>) ((ParameterizedType) t).getRawType(); } } return Object.class; } public static Type getParamGenericType(Class<?> clazz, Type genericType, int ArgumentIndex) { if (genericType == null) { genericType = clazz.getGenericSuperclass(); } if (!(genericType instanceof ParameterizedType)) { genericType = getGenericParamType(genericType); } if (genericType instanceof ParameterizedType) { return ((ParameterizedType) genericType).getActualTypeArguments()[ArgumentIndex]; } return Object.class; } public static Class<?> getParamRawType(Class<?> clazz, int ArgumentIndex) { return getParamRawType(clazz, null, ArgumentIndex); } public static Type getParamGenericType(Class<?> clazz, int ArgumentIndex) { return getParamGenericType(clazz, null, ArgumentIndex); } public static Class<?> getCollectionElementRawType(Class<?> clazz, Type genericType) { return getParamRawType(clazz, genericType, 0); } public static Type getCollectionElementGenericType(Class<?> clazz, Type genericType) { return getParamGenericType(clazz, genericType, 0); } public static Class<?> getMapKeyRawType(Class<?> clazz, Type genericType) { return getParamRawType(clazz, genericType, 0); } public static Class<?> getMapValueRawType(Class<?> clazz, Type genericType) { return getParamRawType(clazz, genericType, 1); } public static Type getMapValueGenericType(Class<?> clazz, Type genericType) { return getParamGenericType(clazz, genericType, 1); } public static Object valueOfEnum(Class<?> clazz, String name) { try { return Enum.valueOf((Class<Enum>) clazz, name); } catch (Exception e) { return null; } } }