package reflection; |
002 |
003 | import java.lang.reflect.Field; |
004 | import java.lang.reflect.Modifier; |
005 | import java.lang.reflect.ParameterizedType; |
006 | import java.lang.reflect.Type; |
007 | import java.util.ArrayList; |
008 | import java.util.Collection; |
009 | import java.util.List; |
010 |
011 | import org.apache.commons.beanutils.PropertyUtils; |
012 | import org.apache.commons.lang.StringUtils; |
013 | import org.slf4j.Logger; |
014 | import org.slf4j.LoggerFactory; |
015 | import org.springframework.util.Assert; |
016 |
017 | /** |
018 | * 反射的Utils函数集合. 提供访问私有变量,获取泛型类型Class,提取集合中元素的属性等Utils函数. |
019 | * |
020 | * @author lei |
021 | */ |
022 | public class ReflectionUtils { |
023 |
024 | private static Logger logger = LoggerFactory.getLogger(ReflectionUtils. class ); |
025 |
026 | private ReflectionUtils() { |
027 | } |
028 |
029 | /** |
030 | * 直接读取对象属性值,无视private/protected修饰符,不经过getter函数. |
031 | */ |
032 | public static Object getFieldValue( final Object object, final String fieldName) { |
033 | Field field = getDeclaredField(object, fieldName); |
034 |
035 | if (field == null ) |
036 | throw new IllegalArgumentException( "Could not find field [" + fieldName + "] on target [" + object + "]" ); |
037 |
038 | makeAccessible(field); |
039 |
040 | Object result = null ; |
041 | try { |
042 | result = field.get(object); |
043 | } catch (IllegalAccessException e) { |
044 | logger.error( "不可能抛出的异常{}" , e.getMessage()); |
045 | } |
046 | return result; |
047 | } |
048 |
049 | /** |
050 | * 直接设置对象属性值,无视private/protected修饰符,不经过setter函数. |
051 | */ |
052 | public static void setFieldValue( final Object object, final String fieldName, final Object value) { |
053 | Field field = getDeclaredField(object, fieldName); |
054 |
055 | if (field == null ) |
056 | throw new IllegalArgumentException( "Could not find field [" + fieldName + "] on target [" + object + "]" ); |
057 |
058 | makeAccessible(field); |
059 |
060 | try { |
061 | field.set(object, value); |
062 | } catch (IllegalAccessException e) { |
063 | logger.error( "不可能抛出的异常:{}" , e.getMessage()); |
064 | } |
065 | } |
066 |
067 | /** |
068 | * 循环向上转型,获取对象的DeclaredField. |
069 | */ |
070 | protected static Field getDeclaredField( final Object object, final String fieldName) { |
071 | Assert.notNull(object, "object不能为空" ); |
072 | return getDeclaredField(object.getClass(), fieldName); |
073 | } |
074 |
075 | /** |
076 | * 循环向上转型,获取类的DeclaredField. |
077 | */ |
078 | @SuppressWarnings ( "unchecked" ) |
079 | protected static Field getDeclaredField( final Class clazz, final String fieldName) { |
080 | Assert.notNull(clazz, "clazz不能为空" ); |
081 | Assert.hasText(fieldName, "fieldName" ); |
082 | for (Class superClass = clazz; superClass != Object. class ; superClass = superClass.getSuperclass()) { |
083 | try { |
084 | return superClass.getDeclaredField(fieldName); |
085 | } catch (NoSuchFieldException e) { |
086 | // Field不在当前类定义,继续向上转型 |
087 | } |
088 | } |
089 | return null ; |
090 | } |
091 |
092 | /** |
093 | * 强制转换fileld可访问. |
094 | */ |
095 | protected static void makeAccessible( final Field field) { |
096 | if (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) { |
097 | field.setAccessible( true ); |
098 | } |
099 | } |
100 |
101 | /** |
102 | * 通过反射,获得定义Class时声明的父类的泛型参数的类型. 如public UserDao extends HibernateDao<User> |
103 | * |
104 | * @param clazz |
105 | * The class to introspect |
106 | * @return the first generic declaration, or Object.class if cannot be |
107 | * determined |
108 | */ |
109 | @SuppressWarnings ( "unchecked" ) |
110 | public static Class getSuperClassGenricType( final Class clazz) { |
111 | return getSuperClassGenricType(clazz, 0 ); |
112 | } |
113 |
114 | /** |
115 | * 通过反射,获得定义Class时声明的父类的泛型参数的类型. 如public UserDao extends |
116 | * HibernateDao<User,Long> |
117 | * |
118 | * @param clazz |
119 | * clazz The class to introspect |
120 | * @param index |
121 | * the Index of the generic ddeclaration,start from 0. |
122 | * @return the index generic declaration, or Object.class if cannot be |
123 | * determined |
124 | */ |
125 |
126 | @SuppressWarnings ( "unchecked" ) |
127 | public static Class getSuperClassGenricType( final Class clazz, final int index) { |
128 |
129 | Type genType = clazz.getGenericSuperclass(); |
130 |
131 | if (!(genType instanceof ParameterizedType)) { |
132 | logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType" ); |
133 | return Object. class ; |
134 | } |
135 |
136 | Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); |
137 |
138 | if (index >= params.length || index < 0 ) { |
139 | logger.warn( "Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + params.length); |
140 | return Object. class ; |
141 | } |
142 | if (!(params[index] instanceof Class)) { |
143 | logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter" ); |
144 | return Object. class ; |
145 | } |
146 | return (Class) params[index]; |
147 | } |
148 |
149 | /** |
150 | * 提取集合中的对象的属性,组合成List. |
151 | * |
152 | * @param collection |
153 | * 来源集合. |
154 | * @param propertityName |
155 | * 要提取的属性名. |
156 | */ |
157 | @SuppressWarnings ( "unchecked" ) |
158 | public static List fetchElementPropertyToList( final Collection collection, final String propertyName) throws Exception { |
159 |
160 | List list = new ArrayList(); |
161 |
162 | for (Object obj : collection) { |
163 | list.add(PropertyUtils.getProperty(obj, propertyName)); |
164 | } |
165 |
166 | return list; |
167 | } |
168 |
169 | /** |
170 | * 提取集合中的对象的属性,组合成由分割符分隔的字符串. |
171 | * |
172 | * @param collection |
173 | * 来源集合. |
174 | * @param propertityName |
175 | * 要提取的属性名. |
176 | * @param separator |
177 | * 分隔符. |
178 | */ |
179 | @SuppressWarnings ( "unchecked" ) |
180 | public static String fetchElementPropertyToString( final Collection collection, final String propertyName, final String separator) throws Exception { |
181 | List list = fetchElementPropertyToList(collection, propertyName); |
182 | return StringUtils.join(list.toArray(), separator); |
183 | } |
184 | } |