Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.polaris.core.reflect.Reflects Maven / Gradle / Ivy
package io.polaris.core.reflect;
import java.beans.Introspector;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
import io.polaris.core.collection.Iterables;
import io.polaris.core.consts.CharConsts;
import io.polaris.core.lang.Types;
import io.polaris.core.map.Maps;
/**
* @author Qt
* @since 1.8
*/
@SuppressWarnings({"unchecked", "unused", "rawtypes"})
public class Reflects {
public static final String TO_STRING = "toString";
public static final String HASH_CODE = "hashCode";
public static final String EQUALS = "equals";
public static final String GET_CLASS = "getClass";
public static final String CLONE = "clone";
public static final String FINALIZE = "finalize";
public static final String WAIT = "wait";
public static final String NOTIFY = "notify";
public static final String NOTIFY_ALL = "notifyAll";
public static final String SET = "set";
public static final String IS = "is";
public static final String GET = "get";
public static final String ANNOTATION_TYPE = "annotationType";
public static final String MAIN_METHOD = "main";
public static final Class>[] MAIN_METHOD_ARGS = {String[].class};
private static final Map, Constructor>[]> CONSTRUCTORS_CACHE = Maps.newWeakKeyMap(new ConcurrentHashMap<>());
private static final Map, Field[]> FIELDS_CACHE = Maps.newWeakKeyMap(new ConcurrentHashMap<>());
private static final Map, Method[]> METHODS_CACHE = Maps.newWeakKeyMap(new ConcurrentHashMap<>());
/**
* 获取指定类型的继承自泛型类声明的方法的返回值实参
*/
public static Class findMethodGenericReturnType(Method method, Class targetType) {
Type genericReturnType = method.getGenericReturnType();
if (genericReturnType instanceof TypeVariable) {
GenericDeclaration genericDeclaration = ((TypeVariable) genericReturnType).getGenericDeclaration();
TypeVariable>[] typeParameters = genericDeclaration.getTypeParameters();
int idx = -1;
for (int i = 0; i < typeParameters.length; i++) {
TypeVariable> typeParameter = typeParameters[i];
if (typeParameter == genericReturnType) {
idx = i;
break;
}
}
if (idx >= 0) {
return findActualTypeArgument(method.getDeclaringClass(), targetType, idx);
}
}
return null;
}
/**
* 得到指定类型的指定位置的泛型实参
*
* @param parameterizedSuperType 泛型基类
* @param obj 目标类
* @param index 位置
* @return 泛型实参
*/
public static Class findActualTypeArgument(Class parameterizedSuperType, Object obj, int index) {
return findActualTypeArgument(parameterizedSuperType, obj.getClass(), index);
}
/**
* 得到指定类型的指定位置的泛型实参
*
* @param parameterizedSuperType 泛型基类
* @param targetClass 目标类
* @param index 位置
* @return 泛型实参
*/
public static Class findActualTypeArgument(Class parameterizedSuperType, Class targetClass, int index) {
if (parameterizedSuperType == targetClass || !parameterizedSuperType.isAssignableFrom(targetClass)) {
return null;
}
TypeVariable extends Class>[] typeParameters = parameterizedSuperType.getTypeParameters();
if (typeParameters.length <= index) {
return null;
}
Deque q = findParameterizedTypes(parameterizedSuperType, targetClass);
int i = index;
for (ParameterizedType t = q.pollLast(); t != null; t = q.pollLast()) {
Type[] actualTypeArguments = t.getActualTypeArguments();
if (actualTypeArguments[i] instanceof Class) {
return (Class) actualTypeArguments[i];
} else if (actualTypeArguments[i] instanceof WildcardType) {
final Type[] upperBounds = ((WildcardType) actualTypeArguments[i]).getUpperBounds();
if (upperBounds.length == 1) {
return Types.getClass(upperBounds[0]);
}
return Object.class;
} else if (actualTypeArguments[i] instanceof ParameterizedType) {
Type rawType = ((ParameterizedType) actualTypeArguments[i]).getRawType();
if (rawType instanceof Class) {
return (Class) rawType;
} else {
return Object.class;
}
} else if (actualTypeArguments[i] instanceof TypeVariable) {
for (int j = 0; j < i; j++) {
if (actualTypeArguments[j] instanceof Class) {
i--;
}
}
} else if (actualTypeArguments[i] instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) actualTypeArguments[i]).getGenericComponentType();
Class> componentClass = Types.getClass(componentType);
return Types.getArrayClass(componentClass);
}
}
return null;
}
@SuppressWarnings("DuplicatedCode")
static Deque findParameterizedTypes(Class parameterizedSuperType, Class targetClass) {
Deque q = new ArrayDeque<>();
// region search
Class that = targetClass;
search:
while (true) {
//superclass
Type genericSuperclass = that.getGenericSuperclass();
if (genericSuperclass != null) {
if (parameterizedSuperType == genericSuperclass) {
break search;
}
if (genericSuperclass instanceof ParameterizedType) {
Type rawType = ((ParameterizedType) genericSuperclass).getRawType();
if (parameterizedSuperType == rawType) {
q.offerLast((ParameterizedType) genericSuperclass);
break search;
} else if (rawType instanceof Class && parameterizedSuperType.isAssignableFrom((Class) rawType)) {
that = (Class) rawType;
q.offerLast((ParameterizedType) genericSuperclass);
continue search;
}
} else if (genericSuperclass instanceof Class && parameterizedSuperType.isAssignableFrom((Class) genericSuperclass)) {
that = (Class) genericSuperclass;
continue search;
}
}
//interfaces
Type[] genericInterfaces = that.getGenericInterfaces();
for (Type genericInterface : genericInterfaces) {
if (parameterizedSuperType == genericInterface) {
break search;
}
if (genericInterface instanceof ParameterizedType) {
Type rawType = ((ParameterizedType) genericInterface).getRawType();
if (parameterizedSuperType == rawType) {
q.offerLast((ParameterizedType) genericInterface);
break search;
} else if (rawType instanceof Class && parameterizedSuperType.isAssignableFrom((Class) rawType)) {
that = (Class) rawType;
q.offerLast((ParameterizedType) genericInterface);
continue search;
}
} else if (genericInterface instanceof Class && parameterizedSuperType.isAssignableFrom((Class) genericInterface)) {
that = (Class) genericInterface;
continue search;
}
}
// never or error
break search;
}
// endregion
return q;
}
/**
* 得到指定类型的最近的泛型信息中指定位置的实参
*/
public static Class findActualTypeArgument(Class clazz, int index) {
Class[] actualTypeArguments = findActualTypeArguments(clazz);
if (actualTypeArguments == null || actualTypeArguments.length == 0) {
return null;
}
return actualTypeArguments[index];
}
public static Class firstParameterizedType(Class clazz) {
return findActualTypeArgument(clazz, 0);
}
/**
* 获取类型的最近的泛型参数
*/
public static Class[] findActualTypeArguments(Class clazz) {
Deque parameterizedTypes = findAllParameterizedTypes(clazz);
if (parameterizedTypes.isEmpty()) {
return null;
}
ParameterizedType parameterizedType = parameterizedTypes.peekFirst();
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
Class[] types = new Class[actualTypeArguments.length];
for (int i = 0; i < types.length; i++) {
types[i] = Types.getClass(actualTypeArguments[i]);
}
return types;
}
/**
* 获取类型的最近的所有泛型信息
*/
static Deque findAllParameterizedTypes(Class clazz) {
Deque rs = new ArrayDeque<>();
Deque q = new ArrayDeque<>();
q.offerLast(clazz);
while (!q.isEmpty()) {
Type type = q.pollFirst();
if (type instanceof ParameterizedType) {
rs.offerLast((ParameterizedType) type);
} else if (type instanceof Class) {
if (!((Class) type).isInterface()) {
Type genericSuperclass = ((Class) type).getGenericSuperclass();
if (genericSuperclass != null && genericSuperclass != Object.class) {
q.offerLast(genericSuperclass);
}
}
Type[] genericInterfaces = ((Class) type).getGenericInterfaces();
for (Type genericInterface : genericInterfaces) {
q.offerLast(genericInterface);
}
}
}
return rs;
}
private static String toGetterOrSetterName(String name) {
if (name.startsWith(GET) || name.startsWith(SET)) {
name = name.substring(3);
} else if (name.startsWith(IS)) {
name = name.substring(2);
}
return Introspector.decapitalize(name);
}
public static String getLambdaMethodName(MethodReferenceReflection f) {
return f.serialized().getImplMethodName();
}
public static String getPropertyName(SerializableSupplier getter) {
return toGetterOrSetterName(getter.method().getName());
}
public static String getPropertyName(SerializableConsumer setter) {
return toGetterOrSetterName(setter.method().getName());
}
public static String getPropertyName(GetterFunction getter) {
return toGetterOrSetterName(getter.method().getName());
}
public static String getPropertyName(SetterFunction setter) {
return toGetterOrSetterName(setter.method().getName());
}
public static void setAccessible(AccessibleObject accessibleObject) {
if ((null != accessibleObject) && (!accessibleObject.isAccessible())) {
accessibleObject.setAccessible(true);
}
}
public static Constructor getConstructor(@Nonnull Class clazz, Class>... parameterTypes) {
final Constructor>[] constructors = getConstructors(clazz);
Class>[] pts;
for (Constructor> constructor : constructors) {
pts = constructor.getParameterTypes();
if (Iterables.isMatchAll(pts, parameterTypes, (c1, c2) -> c1 == c2)) {
setAccessible(constructor);
return (Constructor) constructor;
}
}
for (Constructor> constructor : constructors) {
pts = constructor.getParameterTypes();
if (Iterables.isMatchAll(pts, parameterTypes, Class::isAssignableFrom)) {
setAccessible(constructor);
return (Constructor) constructor;
}
}
return null;
}
public static Constructor[] getConstructors(@Nonnull Class beanClass) {
return (Constructor[]) CONSTRUCTORS_CACHE.computeIfAbsent(beanClass, (c) -> getConstructorsDirectly(beanClass));
}
public static Constructor[] getConstructorsDirectly(@Nonnull Class beanClass) {
return (Constructor[]) beanClass.getDeclaredConstructors();
}
/**
* 获得一个类中所有字段列表,包括其父类中的字段,子类字段在前
*/
public static Field[] getFields(Class> beanClass) {
return FIELDS_CACHE.computeIfAbsent(beanClass, (c) -> getFieldsDirectly(beanClass, true));
}
@SuppressWarnings({"UseBulkOperation", "ManualArrayToCollectionCopy"})
public static Field[] getFieldsDirectly(Class> beanClass, boolean withSuperClassFields) {
Class> searchType = beanClass;
List list = new ArrayList<>();
while (searchType != null) {
Field[] declaredFields = searchType.getDeclaredFields();
for (Field field : declaredFields) {
list.add(field);
}
searchType = withSuperClassFields ? searchType.getSuperclass() : null;
}
return list.toArray(new Field[0]);
}
public static Field[] getFields(Class> beanClass, Predicate fieldFilter) {
return Arrays.stream(getFields(beanClass)).filter(fieldFilter).toArray(Field[]::new);
}
public static Field getField(Class> beanClass, String name) {
final Field[] fields = getFields(beanClass);
return Arrays.stream(getFields(beanClass)).filter(f -> f.getName().equals(name)).findFirst().orElse(null);
}
public static Map getFieldMap(Class> beanClass) {
final Field[] fields = getFields(beanClass);
Map map = new HashMap<>((int) (fields.length * 1.5));
for (Field field : fields) {
map.putIfAbsent(field.getName(), field);
}
return map;
}
public static Object getFieldValueQuietly(Object o, String name) {
try {
return getFieldValue(o, name);
} catch (ReflectiveOperationException e) {
return null;
}
}
public static Object getFieldValue(Object o, String name) throws ReflectiveOperationException {
Field field = getField(o.getClass(), name);
if (field == null) {
return null;
}
setAccessible(field);
if (Modifier.isStatic(field.getModifiers())) {
return field.get(null);
} else {
return field.get(o);
}
}
public static void setFieldValue(Object o, String name, Object value) throws ReflectiveOperationException {
Field field = getField(o.getClass(), name);
if (field == null) {
return;
}
if (!field.getType().isAssignableFrom(value.getClass())) {
throw new IllegalArgumentException();
}
setAccessible(field);
if (Modifier.isStatic(field.getModifiers())) {
field.set(null, value);
} else {
field.set(o, value);
}
}
private static String toMethodKey(Method method) {
final StringBuilder sb = new StringBuilder();
sb.append(method.getName()).append("(");
Class>[] parameters = method.getParameterTypes();
for (int i = 0; i < parameters.length; i++) {
if (i > 0) {
sb.append(',');
}
sb.append(parameters[i].getName());
}
sb.append("):").append(method.getReturnType().getName());
return sb.toString();
}
/**
* 获得一个类中所有方法列表,包括其父类中的方法
*/
public static Method[] getMethods(Class> beanClass) {
return METHODS_CACHE.computeIfAbsent(beanClass,
(c) -> getMethodsDirectly(beanClass, true, true));
}
/**
* 获得一个类中所有方法列表
*
* @param beanClass 类或接口
* @param withSupers 是否包括父类或接口的方法列表
* @param withMethodFromObject 是否包括Object中的方法
* @return methods
*/
public static Method[] getMethodsDirectly(Class> beanClass, boolean withSupers, boolean withMethodFromObject) {
if (beanClass.isInterface()) {
// 对于接口,直接调用Class.getMethods方法获取所有方法
return withSupers ? beanClass.getMethods() : beanClass.getDeclaredMethods();
}
Map map = new LinkedHashMap<>();
Class> searchType = beanClass;
while (searchType != null) {
if (!withMethodFromObject && Object.class == searchType) {
break;
}
// 本类定义的方法
for (Method m : searchType.getDeclaredMethods()) {
map.putIfAbsent(toMethodKey(m), m);
}
// 对应接口中的非抽象方法(default方法)
for (Class> ifc : searchType.getInterfaces()) {
for (Method m : ifc.getMethods()) {
if (!Modifier.isAbstract(m.getModifiers())) {
map.putIfAbsent(toMethodKey(m), m);
}
}
}
searchType = (withSupers && !searchType.isInterface()) ? searchType.getSuperclass() : null;
}
return map.values().toArray(new Method[0]);
}
public static Method[] getMethods(Class> clazz, Predicate filter) {
return Arrays.stream(getMethods(clazz)).filter(filter).toArray(Method[]::new);
}
public static Set getMethodNames(Class> clazz) {
Set methodSet = new HashSet<>();
Method[] methods = getMethods(clazz);
for (Method method : methods) {
methodSet.add(method.getName());
}
return methodSet;
}
/**
* 按照方法名查找指定方法名的方法,只返回匹配到的第一个方法,如果找不到对应的方法则返回null
*/
public static Method getMethodByName(Class> clazz, String methodName) {
return getMethodByName(clazz, methodName, false);
}
/**
* 按照方法名查找指定方法名的方法,只返回匹配到的第一个方法,如果找不到对应的方法则返回null
*/
public static Method getMethodByName(Class> clazz, String methodName, boolean ignoreCase) {
Method[] methods = getMethods(clazz);
if (ignoreCase) {
for (Method method : methods) {
if (method.getName().equalsIgnoreCase(methodName)) {
return method;
}
}
} else {
for (Method method : methods) {
if (method.getName().equals(methodName)) {
return method;
}
}
}
return null;
}
public static Method getMethod(Class> clazz, String methodName, Class>... paramTypes) {
Method[] methods = getMethods(clazz);
for (Method method : methods) {
if (method.getName().equalsIgnoreCase(methodName)) {
if (Iterables.isMatchAll(method.getParameterTypes(), paramTypes, (c1, c2) -> c1 == c2)) {
return method;
}
}
}
for (Method method : methods) {
if (method.getName().equalsIgnoreCase(methodName)) {
if (Iterables.isMatchAll(method.getParameterTypes(), paramTypes, Class::isAssignableFrom)) {
return method;
}
}
}
return null;
}
public static boolean isGetterMethod(Method method) {
return method != null && method.getParameterCount() == 0 && method.getName().length() > 2
&&
(method.getName().startsWith(IS) && method.getReturnType() == boolean.class
|| method.getName().startsWith(GET) && method.getReturnType() != void.class)
;
}
public static boolean isSetterMethod(Method method) {
return method != null && method.getParameterCount() == 1
&& method.getName().length() > 3 && method.getName().startsWith(SET);
}
public static boolean isEqualsMethod(Method method) {
if (method == null || method.getParameterCount() != 1 || !EQUALS.equals(method.getName())) {
return false;
}
return (method.getParameterTypes()[0] == Object.class);
}
public static boolean isHashCodeMethod(Method method) {
return method != null && HASH_CODE.equals(method.getName()) && method.getParameterCount() == 0;
}
public static boolean isToStringMethod(Method method) {
return method != null && TO_STRING.equals(method.getName()) && method.getParameterCount() == 0;
}
public static boolean isGetClassMethod(Method method) {
return method != null && GET_CLASS.equals(method.getName()) && method.getParameterCount() == 0;
}
public static boolean isCloneMethod(Method method) {
return method != null && CLONE.equals(method.getName()) && method.getParameterCount() == 0;
}
public static boolean isNotifyMethod(Method method) {
return method != null && NOTIFY.equals(method.getName()) && method.getParameterCount() == 0;
}
public static boolean isNotifyAllMethod(Method method) {
return method != null && NOTIFY_ALL.equals(method.getName()) && method.getParameterCount() == 0;
}
public static boolean isWaitMethod(Method method) {
return method != null && WAIT.equals(method.getName()) &&
(
method.getParameterCount() == 0
|| method.getParameterCount() == 1 && method.getParameterTypes()[0] == long.class
|| method.getParameterCount() == 2 && method.getParameterTypes()[0] == long.class && method.getParameterTypes()[1] == int.class
);
}
public static boolean isFinalizeMethod(Method method) {
return method != null && FINALIZE.equals(method.getName()) && method.getParameterCount() == 0;
}
public boolean isAnnotationTypeMethod(Method method) {
return method != null && ANNOTATION_TYPE.equals(method.getName()) && method.getParameterCount() == 0;
}
public static boolean isObjectDeclaredMethod(Method method) {
return isEqualsMethod(method) || isHashCodeMethod(method) || isToStringMethod(method) || isGetClassMethod(method)
|| isCloneMethod(method) || isNotifyMethod(method) || isNotifyAllMethod(method)
|| isWaitMethod(method) || isFinalizeMethod(method)
;
}
public static Method getPublicMethod(Class> clazz, String methodName, Class>... paramTypes) {
try {
return clazz.getMethod(methodName, paramTypes);
} catch (NoSuchMethodException ex) {
return null;
}
}
/**
* 获得本类及其父类所有Public方法
*/
public static Method[] getPublicMethods(Class> clazz) {
return null == clazz ? null : clazz.getMethods();
}
public static List getPublicMethods(Class> clazz, Predicate filter) {
Method[] methods = getPublicMethods(clazz);
List methodList = new ArrayList<>();
for (Method method : methods) {
if (filter.test(method)) {
methodList.add(method);
}
}
return methodList;
}
public static T newInstance(String className) throws ReflectiveOperationException {
return (T) newInstance(Class.forName(className));
}
public static T newInstance(Class clazz, Class[] paramTypes, Object[] params) throws ReflectiveOperationException {
Constructor constructor = getConstructor(clazz, paramTypes);
if (constructor != null) {
return constructor.newInstance(params);
}
throw new NoSuchMethodException();
}
public static T newInstance(Class clazz, Object... params) throws ReflectiveOperationException {
if (params.length == 0) {
Constructor constructor = getConstructor(clazz);
if (constructor != null) {
return constructor.newInstance();
}
constructor = getConstructor(clazz, Object[].class);
if (constructor != null) {
return constructor.newInstance((Object[]) params);
}
} else {
Class>[] paramTypes = new Class[params.length];
for (int i = 0; i < params.length; i++) {
paramTypes[i] = params[i] == null ? Object.class : params[i].getClass();
}
Constructor constructor = getConstructor(clazz, paramTypes);
if (constructor != null) {
return constructor.newInstance(params);
}
}
throw new NoSuchMethodException();
}
@SuppressWarnings("unchecked")
public static T newInstanceIfPossible(Class type) {
if (Types.isPrimitiveWrapper(type)) {
type = Types.getPrimitiveClassByWrapper(type);
}
if (type.isPrimitive()) {
return (T) Types.getDefaultValue(type);
}
// 某些特殊接口的实例化按照默认实现进行
if (type.isAssignableFrom(AbstractMap.class)) {
type = (Class) HashMap.class;
} else if (type.isAssignableFrom(ConcurrentNavigableMap.class)) {
type = (Class) ConcurrentSkipListMap.class;
} else if (type.isAssignableFrom(ConcurrentMap.class)) {
type = (Class) ConcurrentHashMap.class;
} else if (type.isAssignableFrom(NavigableMap.class)) {
type = (Class) TreeMap.class;
} else if (type.isAssignableFrom(List.class)) {
type = (Class) ArrayList.class;
} else if (type.isAssignableFrom(Set.class)) {
type = (Class) HashSet.class;
} else if (type.isAssignableFrom(BlockingDeque.class)) {
type = (Class) LinkedBlockingDeque.class;
} else if (type.isAssignableFrom(Deque.class)) {
type = (Class) ArrayDeque.class;
}
try {
return newInstance(type);
} catch (Exception ignore) {
}
// 枚举
if (type.isEnum()) {
return type.getEnumConstants()[0];
}
// 数组
if (type.isArray()) {
return (T) Array.newInstance(type.getComponentType(), 0);
}
final Constructor[] constructors = getConstructors(type);
Class>[] parameterTypes;
for (Constructor constructor : constructors) {
parameterTypes = constructor.getParameterTypes();
if (0 == parameterTypes.length) {
continue;
}
setAccessible(constructor);
try {
return constructor.newInstance(Types.getDefaultValues(parameterTypes));
} catch (Exception ignore) {
}
}
return null;
}
public static T invokeStatic(Method method, Object... args) throws ReflectiveOperationException {
return invoke(null, method, args);
}
public static T invoke(Object obj, Method method, Object... args) throws ReflectiveOperationException {
setAccessible(method);
return (T) method.invoke(Modifier.isStatic(method.getModifiers()) ? null : obj, args);
}
public static T invokeQuietly(Object obj, Method method, Object... args) {
try {
return invoke(obj, method, args);
} catch (ReflectiveOperationException ignore) {
return null;
}
}
public Object invokeMain(Class clazz) throws ReflectiveOperationException {
return invokeMain(clazz, new String[0]);
}
public Object invokeMain(Class clazz, String... mainArgs) throws ReflectiveOperationException {
Method main = clazz.getMethod(MAIN_METHOD, MAIN_METHOD_ARGS);
return main.invoke(null, new Object[]{mainArgs});
}
public T invoke(Class clazz, String methodName, Class[] paramTypes, Object[] paramValues) throws ReflectiveOperationException {
Method method = Reflects.getMethod(clazz, methodName, paramTypes);
if (method == null) {
return null;
}
if (Modifier.isStatic(method.getModifiers())) {
return (T) Reflects.invoke(null, method, paramValues);
}
Object o = Reflects.newInstanceIfPossible(clazz);
return (T) Reflects.invoke(o, method, paramValues);
}
/**
* 设置final的field字段可以被修改
* 只要不会被编译器内联优化的 final 属性就可以通过反射进行修改
* 以下属性,编译器会内联优化,无法通过反射修改:
* 基本类型 byte, char, short, int, long, float, double, boolean
* Literal String 类型(直接双引号字符串)
*
*
* 以下属性,可以通过反射修改:
* 基本类型的包装类 Byte、Character、Short、Long、Float、Double、Boolean
* 字符串,通过 new String("")实例化
* 自定义java类
*
*/
public static boolean removeFinalModifier(Field field) throws ReflectiveOperationException {
if (Modifier.isFinal(field.getModifiers())) {
setAccessible(field);
//去除final修饰符的影响,将字段设为可修改的
final Field modifiersField = Field.class.getDeclaredField("modifiers");
//Field 的 modifiers 是私有的
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
return true;
}
return false;
}
public static Class> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, null);
}
public static Class> loadClass(String name, ClassLoader classLoader) throws ClassNotFoundException {
name = name.replace(CharConsts.SLASH, CharConsts.DOT);
if (classLoader == null) {
classLoader = Thread.currentThread().getContextClassLoader();
}
Class type = Types.getPrimitiveClassByName(name);
if (type == null) {
type = doLoadClass(name, classLoader);
}
return type;
}
private static Class doLoadClass(String name, ClassLoader classLoader) throws ClassNotFoundException {
Class> clazz;
if (name.endsWith("[]")) {
// xx[]
final String elementClassName = name.substring(0, name.length() - 2);
final Class> elementClass = loadClass(elementClassName, classLoader);
clazz = Array.newInstance(elementClass, 0).getClass();
} else if (name.startsWith("[L") && name.endsWith(";")) {
// [Lxx;
final String elementName = name.substring(2, name.length() - 1);
final Class> elementClass = loadClass(elementName, classLoader);
clazz = Array.newInstance(elementClass, 0).getClass();
} else if (name.startsWith("[")) {
// [[I , [[Lxx;
final String elementName = name.substring(1);
final Class> elementClass = loadClass(elementName, classLoader);
clazz = Array.newInstance(elementClass, 0).getClass();
} else {
try {
clazz = Class.forName(name, true, classLoader);
} catch (ClassNotFoundException ex) {
// 尝试获取内部类,例如java.lang.Thread.State =》java.lang.Thread$State
clazz = tryLoadInnerClass(name, classLoader);
if (null == clazz) {
throw ex;
}
}
}
return clazz;
}
private static Class> tryLoadInnerClass(String name, ClassLoader classLoader) {
int lastDotIndex = name.lastIndexOf(CharConsts.DOT);
if (lastDotIndex > 0) {
String innerClassName = name.substring(0, lastDotIndex) + '$' + name.substring(lastDotIndex + 1);
try {
return Class.forName(innerClassName, true, classLoader);
} catch (ClassNotFoundException e) {
return tryLoadInnerClass(innerClassName, classLoader);
}
}
return null;
}
}