/* * JEF - Copyright 2009-2010 Jiyi (mr.jiyi@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jef.tools.reflect; import java.io.InputStream; import java.lang.annotation.Annotation; 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.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import javax.management.ReflectionException; import jef.common.log.LogUtil; import jef.tools.Assert; import jef.tools.StringUtils; import jef.tools.collection.CollectionUtils; import jef.tools.reflect.BeanUtils.SearchMode; /** * 带有泛型上下文的Class对象的封装。 * 可以当做Class来使用 * @author jiyi */ public class ClassEx { /** * Class对象 */ private Class<?> cls; /** * 完整的泛型上下文 */ Type genericType; /** * context */ private ClassEx instanceClz; /** * 装箱 * @param clz * @return */ public static ClassEx valueOf(Class<?> clz) { return new ClassEx(clz); } public Class<?> classValue(){ return this.cls; } public ClassEx(Type type) { this.genericType = type; this.cls = GenericUtils.getRawClass(type); Assert.notNull(cls); } public ClassEx(Class<?> cls) { if (isCGLibProxy(cls)) { cls = cls.getSuperclass(); } this.genericType = cls; this.cls = cls; } /** * 得到被包装的类型本身 * * @return */ public Class<?> getWrappered() { return cls; } /** * 得到被包装的泛型 * * @return */ public Type getGenericType() { return genericType; } /** * 使用带参数的构造器生成对象 * * @param params * @return * @throws ReflectionException */ public Object newInstance(Object... params) throws ReflectionException { return BeanUtils.newInstance(cls, params); } /** * 使用空参数构造,无视构造参数一律传null */ public Object newInstanceAnyway() throws ReflectionException { return BeanUtils.newInstanceAnyway(cls); } /** * 调用该类的某个静态方法 * * @param method * @param params * @return * @throws ReflectionException */ public Object invokeStaticMethod(String method, Object... params) throws ReflectionException { return innerInvoke(null, method, true, params); } /** * 用不带参数的构造器构造对象,然后运行指定的方法 * * @param method * @param params * @return * @throws ReflectionException */ public Object invokeWithNewInstance(String method, Object... params) throws ReflectionException { return innerInvoke(newInstanceAnyway(), method, false, params); } /* * obj:对象 method方法名,isStatic静态方法,params:参数 */ Object innerInvoke(Object obj, String method, boolean isStatic, Object... params) throws ReflectionException { try { if (obj == null && !isStatic) obj = newInstance(); List<Class<?>> list = new ArrayList<Class<?>>(); for (Object pobj : params) { list.add(pobj.getClass()); } MethodEx me = BeanUtils.getCompatibleMethod(cls, method, list.toArray(new Class[list.size()])); if (me == null) { NoSuchMethodException e = new NoSuchMethodException("Method:[" + cls.getName() + "::" + method + "] not found with param count:" + params.length); throw new ReflectionException(e); } if (!Modifier.isPublic(me.getModifiers()) || !Modifier.isPublic(cls.getModifiers())) { try { me.setAccessible(true); } catch (SecurityException e) { System.out.println(me.toString() + "\n" + e.getMessage()); } } return me.invoke(obj, params); } catch (IllegalAccessException e) { throw new ReflectionException(e); } catch (SecurityException e) { throw new ReflectionException(e); } catch (IllegalArgumentException e) { throw new ReflectionException(e); } catch (InvocationTargetException e) { if (e.getCause() instanceof Exception) { throw new ReflectionException((Exception) e.getCause()); } else { throw new ReflectionException(e); } } } /** * 获得当前类以及其全部父类 */ public static List<Class<?>> withSupers(Class<?> c) { List<Class<?>> supers = new ArrayList<Class<?>>(); supers.add(c); c = c.getSuperclass(); while (c != null) { supers.add(c); c = c.getSuperclass(); } return supers; } public FieldEx[] getDeclaredFields() { Field[] fields = cls.getDeclaredFields(); FieldEx[] result = new FieldEx[fields.length]; for (int i = 0; i < fields.length; i++) { result[i] = new FieldEx(fields[i], instanceClz == null ? this : instanceClz); } return result; } /** * 获得Annotation */ public <T extends Annotation> T getAnnotation(Class<T> t) { return cls.getAnnotation(t); } /** * 返回经过解析的泛型类型 * * @param method * @return */ public Type getMethodReturnType(Method method) { ClassEx cw = this; method = getRealMethod(method); if (method.getDeclaringClass() != this.cls) { Type type = GenericUtils.getSuperType(null, cls, method.getDeclaringClass()); cw = new ClassEx(type); } return GenericUtils.getBoundType(method.getGenericReturnType(), cw); } /** * 返回经过解析的泛型类型 * * @param method * @param index * @return */ public Type getMethodParamType(Method method, int index) { ClassEx cw = this; method = getRealMethod(method); if (method.getDeclaringClass() != this.cls) { Type type = GenericUtils.getSuperType(null, cls, method.getDeclaringClass()); cw = new ClassEx(type); } Type[] types = method.getGenericParameterTypes(); if (index < 0 || index > types.length) { throw new IllegalArgumentException(StringUtils.concat("the method ", method.getName(), " has ", String.valueOf(types.length), " params, index=", String.valueOf(index), " is out of bound.")); } return GenericUtils.getBoundType(types[index], cw); } private Method getRealMethod(Method method) { Class<?> cls = method.getDeclaringClass(); if (isCGLibProxy(cls)) { try { return cls.getSuperclass().getMethod(method.getName(), method.getParameterTypes()); } catch (SecurityException e) { LogUtil.exception(e); } catch (NoSuchMethodException e) { LogUtil.exception(e); } } return method; } /** * 返回经过泛型解析后的方法参数 * * @param method * @return */ public Type[] getMethodParamTypes(Method method) { ClassEx cw = this; method = getRealMethod(method); if (method.getDeclaringClass() != this.cls) { Type type = GenericUtils.getSuperType(null, cls, method.getDeclaringClass()); cw = new ClassEx(type); } Type[] types = method.getGenericParameterTypes(); for (int i = 0; i < types.length; i++) { types[i] = GenericUtils.getBoundType(types[i], cw); } return types; } /** * 排除CGLib的代理类的干扰,得到真正的class * * @param clz * @return */ public static Class<?> getRealClass(Class<?> clz) { if (isCGLibProxy(clz)) { return clz.getSuperclass(); } return clz; } // 判断这个类是不是CGLIB处理过的类 private static boolean isCGLibProxy(Class<?> declaringClass) { return (declaringClass.getName().indexOf("$$EnhancerByCGLIB$$") > -1); } /** * 获得class的全称 * * @return */ public String getName() { return cls.getName(); } /** * 获得class的简称 * * @return */ public String getSimpleName() { return cls.getSimpleName(); } /** * 获得泛型对象的名称 * * @return */ public String getGenericName() { return genericType.toString(); } /** * 得到指定的方法 * * @param name * @param params * @return */ public Method getPublicMethod(String name, Class<?>... params) { try { return cls.getMethod(name, params); } catch (SecurityException e) { throw new IllegalArgumentException(e.getMessage()); } catch (NoSuchMethodException e) { return null; } } /** * 根据名称获得一个方法,前提是方法没有重名。如果没有找到,会到父类中查找 * * @param name * @return */ public MethodEx getMethodByName(String name) { MethodEx[] methods = BeanUtils.getMethodByName(this, name, 1, SearchMode.NOT_IN_SUPER_IF_FOUND); if (methods.length > 1) { throw new IllegalArgumentException("There are more than 1 method match the name " + name + " in class " + cls.getName()); } if (methods.length == 0) return null; return methods[0]; } /** * 获得所有有getter和setter的field * * @return */ public FieldEx[] getFieldsWithGetterAndSetter() { return BeanUtils.getFieldsWithGetterAndSetter(this.cls, Object.class); } public FieldEx[] getFieldsWithGetter() { return BeanUtils.getFieldsWithGetter(this.cls, Object.class); } public FieldEx[] getFieldsWithSetter() { return BeanUtils.getFieldsWithSetter(this.cls, Object.class); } /** * 获得所有field名称 * * @return */ public String[] getFieldNames() { return BeanUtils.getFieldNames(this.cls, Object.class); } /** * 获得所有Field * * @return */ public FieldEx[] getFields() { return BeanUtils.getFields(this.cls, Object.class, false, false); } /** * 获得所有public方法,包括从父类继承到的 * * @return */ public MethodEx[] getMethods() { return BeanUtils.getMethods(this.cls); } /** * 得到字段类型 * * @param name * @return */ public Class<?> getFieldType(String name) { return BeanUtils.getFieldType(cls, name); } /** * 得到经过泛型解析的字段类型 * * @param name * @return */ public Type getFieldGenericType(String name) { return BeanUtils.getField(this, name).getGenericType(); } /** * 得到经过泛型解析的字段类型 * * @param name * @return */ public Type getFieldGenericType(Field field) { Assert.notNull(field); ClassEx cw = this; if (field.getDeclaringClass() != this.cls) { Type type = GenericUtils.getSuperType(null, cls, field.getDeclaringClass()); cw = new ClassEx(type); } return GenericUtils.getBoundType(field.getGenericType(), cw); } /** * 根据类型和加载器构建 * * @param className * @param loder * @return * @throws ReflectionException */ public static final ClassEx getClassEx(String className, ClassLoader loder) throws ReflectionException { try { if (loder == null) loder = ClassEx.class.getClassLoader(); Class<?> c = loder.loadClass(className); return new ClassEx(c); } catch (ClassNotFoundException e) { throw new ReflectionException(e, "Class: " + className + " not found."); } } /** * 构建 * * @param className * @return * @throws ReflectionException */ public static final ClassEx getClassEx(String className) throws ReflectionException { return getClassEx(className, null); } /** * 根据提供的方法名称查找第一个符合名称的方法 * * @param name * @return */ public MethodEx getFirstMethodByName(String name) { MethodEx[] methods = BeanUtils.getMethodByName(this, name, 1, SearchMode.NOT_IN_SUPER_IF_FOUND); if (methods.length > 0) return methods[0]; return null; } /* * 根据指定的泛型变量,查找泛型参数实例 <p>Title: getImplType</p> <p>Description: </p> * * @param declaration * * @return * * @see * jef.tools.reflect.GenericProvider#getImplType(java.lang.reflect.TypeVariable * ) */ public Type getImplType(TypeVariable<?> declaration) { if (declaration.getGenericDeclaration() == this.cls && this.genericType instanceof ParameterizedType) { ParameterizedType pType = (ParameterizedType) genericType; int n = 0; for (TypeVariable<?> tv : cls.getTypeParameters()) { if (tv == declaration) break; n++; } return pType.getActualTypeArguments()[n]; } return null; } public FieldEx getField(String field) { return BeanUtils.getField(this, field); } public MethodEx getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException { return new MethodEx(cls.getMethod(name, parameterTypes), this); } public MethodEx getMethodIfExist(String name, Class<?>... paramTypes) { try { Method method = cls.getMethod(name, paramTypes); return new MethodEx(method, this); } catch (SecurityException e) { LogUtil.exception(e); } catch (NoSuchMethodException e) { LogUtil.exception(e); } return null; } public boolean isInterface() { return cls.isInterface(); } public Class<?> getEnclosingClass() { return cls.getEnclosingClass(); } public int getModifiers() { return cls.getModifiers(); } public Object[] getEnumConstants() { return cls.getEnumConstants(); } public MethodEx getDeclaredMethod(String name, Class<?>... parameterTypes) throws SecurityException, NoSuchMethodException { Method m = cls.getDeclaredMethod(name, parameterTypes); return new MethodEx(m, instanceClz == null ? this : instanceClz); } /** * 不丢失泛型的父类型获取 * * @return */ public ClassEx getSuperclass() { Type s = cls.getGenericSuperclass(); if (s == null) return null; ClassEx result = new ClassEx(s); if (instanceClz != null) { result.instanceClz = instanceClz; } else { result.instanceClz = this; } if (Throwable.class == result.getWrappered()) { return null; } return result; } public MethodEx[] getDeclaredMethods() { Method[] methods = cls.getDeclaredMethods(); MethodEx[] result = new MethodEx[methods.length]; for (int i = 0; i < methods.length; i++) { result[i] = new MethodEx(methods[i], instanceClz == null ? this : instanceClz); } return result; } public FieldEx getDeclaredField(String name) throws SecurityException, NoSuchFieldException { return new FieldEx(cls.getDeclaredField(name), instanceClz == null ? this : instanceClz); } public Constructor<?> getDeclaredConstructor(Class<?>... params) throws SecurityException, NoSuchMethodException { return cls.getDeclaredConstructor(params); } @Override public int hashCode() { return genericType.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof ClassEx) { return this.genericType.equals(((ClassEx) obj).genericType); } return false; } public Package getPackage() { return cls.getPackage(); } public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { return cls.isAnnotationPresent(annotationClass); } @Override public String toString() { return genericType.toString(); } public InputStream getResourceAsStream(String string) { return cls.getResourceAsStream(string); } public ClassLoader getClassLoader() { return cls.getClassLoader(); } public String getPackageName() { String s = cls.getName(); int n = s.lastIndexOf('.'); if (n > -1) { return s.substring(0, n); } else { return ""; } } /** * 获得指定名称的class,并包装成Wrapper * * @param name * @return 如果class获得不成功返回null */ public static ClassEx forName(String name) { Class<?> c = getClass(name); return c == null ? null : new ClassEx(c); } /** * 获得指定名称的class,如果没有返回null * * @param name * @return */ public static Class<?> getClass(String name) { try { return Class.forName(name); } catch (ClassNotFoundException e) { System.err.println("Class:" + name + " not found!"); return null; } } public boolean isAssignableFrom(Class<?> class1) { return cls.isAssignableFrom(class1); } public boolean isGeneric() { return !this.genericType.equals(cls); } public boolean isEnum() { return cls.isEnum(); } public boolean isArray() { return GenericUtils.isArray(genericType); } public boolean isPrimitive() { return this.cls.isPrimitive(); } public boolean isCollection() { return CollectionUtils.isCollection(genericType); } public boolean isMap() { return Map.class.isAssignableFrom(cls); } public Type getComponentType() { return CollectionUtils.getComponentType(genericType); } /** * 返回类所实现的接口 * * @return */ public Class<?>[] getInterfaces() { return cls.getInterfaces(); } /** * 得到该类和父类的全部接口,如果子类父类有相同的接口,只出现一次 * * @return */ public Class<?>[] getAllInterfaces() { LinkedHashSet<Class<?>> intf = new LinkedHashSet<Class<?>>(); Class<?> c = cls; while (c != Object.class && c!=null) { for (Class<?> ic : c.getInterfaces()) { intf.add(ic); } c = c.getSuperclass(); } return intf.toArray(new Class<?>[intf.size()]); } }