Skip to content

Commit b2438ca

Browse files
committed
解决JDK6,7无法获取字段泛型类型的问题。
1 parent 2eab92f commit b2438ca

File tree

4 files changed

+444
-68
lines changed

4 files changed

+444
-68
lines changed

src/main/java/tk/mybatis/mapper/mapperhelper/FieldHelper.java

Lines changed: 257 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@
3131
import java.beans.IntrospectionException;
3232
import java.beans.Introspector;
3333
import java.beans.PropertyDescriptor;
34-
import java.lang.reflect.Field;
35-
import java.lang.reflect.Modifier;
34+
import java.lang.reflect.*;
3635
import java.util.*;
3736

3837
/**
@@ -43,26 +42,35 @@
4342
*/
4443
public class FieldHelper {
4544

45+
private static final IFieldHelper fieldHelper;
46+
47+
static {
48+
String version = System.getProperty("java.version");
49+
if (version.contains("1.8.")) {
50+
fieldHelper = new Jdk8FieldHelper();
51+
} else {
52+
fieldHelper = new Jdk6_7FieldHelper();
53+
}
54+
}
55+
4656
/**
4757
* 获取全部的Field
4858
*
4959
* @param entityClass
5060
* @return
5161
*/
5262
public static List<EntityField> getFields(Class<?> entityClass) {
53-
List<EntityField> fields = _getFields(entityClass, null, null);
54-
List<EntityField> properties = _getProperties(entityClass);
55-
Set<EntityField> usedSet = new HashSet<EntityField>();
56-
for (EntityField field : fields) {
57-
for (EntityField property : properties) {
58-
if (!usedSet.contains(property) && field.getName().equals(property.getName())) {
59-
//泛型的情况下通过属性可以得到实际的类型
60-
field.setJavaType(property.getJavaType());
61-
break;
62-
}
63-
}
64-
}
65-
return fields;
63+
return fieldHelper.getFields(entityClass);
64+
}
65+
66+
/**
67+
* 获取全部的属性,通过方法名获取
68+
*
69+
* @param entityClass
70+
* @return
71+
*/
72+
public static List<EntityField> getProperties(Class<?> entityClass) {
73+
return fieldHelper.getProperties(entityClass);
6674
}
6775

6876
/**
@@ -73,8 +81,8 @@ public static List<EntityField> getFields(Class<?> entityClass) {
7381
* @throws IntrospectionException
7482
*/
7583
public static List<EntityField> getAll(Class<?> entityClass) {
76-
List<EntityField> fields = _getFields(entityClass, null, null);
77-
List<EntityField> properties = _getProperties(entityClass);
84+
List<EntityField> fields = fieldHelper.getFields(entityClass);
85+
List<EntityField> properties = fieldHelper.getProperties(entityClass);
7886
//拼到一起,名字相同的合并
7987
List<EntityField> all = new ArrayList<EntityField>();
8088
Set<EntityField> usedSet = new HashSet<EntityField>();
@@ -97,69 +105,251 @@ public static List<EntityField> getAll(Class<?> entityClass) {
97105
}
98106

99107
/**
100-
* 获取全部的Field,仅仅通过Field获取
101-
*
102-
* @param entityClass
103-
* @param fieldList
104-
* @param level
105-
* @return
108+
* Field接口
106109
*/
107-
private static List<EntityField> _getFields(Class<?> entityClass, List<EntityField> fieldList, Integer level) {
108-
if (fieldList == null) {
109-
fieldList = new ArrayList<EntityField>();
110-
}
111-
if (level == null) {
112-
level = 0;
110+
interface IFieldHelper {
111+
/**
112+
* 获取全部的Field
113+
*
114+
* @param entityClass
115+
* @return
116+
*/
117+
List<EntityField> getFields(Class<?> entityClass);
118+
119+
/**
120+
* 获取全部的属性,通过方法名获取
121+
*
122+
* @param entityClass
123+
* @return
124+
*/
125+
List<EntityField> getProperties(Class<?> entityClass);
126+
}
127+
128+
/**
129+
* 支持jdk8
130+
*/
131+
static class Jdk8FieldHelper implements IFieldHelper {
132+
/**
133+
* 获取全部的Field
134+
*
135+
* @param entityClass
136+
* @return
137+
*/
138+
public List<EntityField> getFields(Class<?> entityClass) {
139+
List<EntityField> fields = _getFields(entityClass, null, null);
140+
List<EntityField> properties = getProperties(entityClass);
141+
Set<EntityField> usedSet = new HashSet<EntityField>();
142+
for (EntityField field : fields) {
143+
for (EntityField property : properties) {
144+
if (!usedSet.contains(property) && field.getName().equals(property.getName())) {
145+
//泛型的情况下通过属性可以得到实际的类型
146+
field.setJavaType(property.getJavaType());
147+
break;
148+
}
149+
}
150+
}
151+
return fields;
113152
}
114-
if (entityClass.equals(Object.class)) {
153+
154+
/**
155+
* 获取全部的Field,仅仅通过Field获取
156+
*
157+
* @param entityClass
158+
* @param fieldList
159+
* @param level
160+
* @return
161+
*/
162+
private List<EntityField> _getFields(Class<?> entityClass, List<EntityField> fieldList, Integer level) {
163+
if (fieldList == null) {
164+
fieldList = new ArrayList<EntityField>();
165+
}
166+
if (level == null) {
167+
level = 0;
168+
}
169+
if (entityClass.equals(Object.class)) {
170+
return fieldList;
171+
}
172+
Field[] fields = entityClass.getDeclaredFields();
173+
int index = 0;
174+
for (int i = 0; i < fields.length; i++) {
175+
Field field = fields[i];
176+
//排除静态字段,解决bug#2
177+
if (!Modifier.isStatic(field.getModifiers())) {
178+
if (level.intValue() != 0) {
179+
//将父类的字段放在前面
180+
fieldList.add(index, new EntityField(field, null));
181+
index++;
182+
} else {
183+
fieldList.add(new EntityField(field, null));
184+
}
185+
}
186+
}
187+
Class<?> superClass = entityClass.getSuperclass();
188+
if (superClass != null
189+
&& !superClass.equals(Object.class)
190+
&& (superClass.isAnnotationPresent(Entity.class)
191+
|| (!Map.class.isAssignableFrom(superClass)
192+
&& !Collection.class.isAssignableFrom(superClass)))) {
193+
return _getFields(entityClass.getSuperclass(), fieldList, ++level);
194+
}
115195
return fieldList;
116196
}
117-
Field[] fields = entityClass.getDeclaredFields();
118-
int index = 0;
119-
for (int i = 0; i < fields.length; i++) {
120-
Field field = fields[i];
121-
//排除静态字段,解决bug#2
122-
if (!Modifier.isStatic(field.getModifiers())) {
123-
if (level.intValue() != 0) {
124-
//将父类的字段放在前面
125-
fieldList.add(index, new EntityField(field, null));
126-
index++;
127-
} else {
128-
fieldList.add(new EntityField(field, null));
197+
198+
/**
199+
* 通过方法获取属性
200+
*
201+
* @param entityClass
202+
* @return
203+
*/
204+
public List<EntityField> getProperties(Class<?> entityClass) {
205+
List<EntityField> entityFields = new ArrayList<EntityField>();
206+
BeanInfo beanInfo = null;
207+
try {
208+
beanInfo = Introspector.getBeanInfo(entityClass);
209+
} catch (IntrospectionException e) {
210+
throw new RuntimeException(e);
211+
}
212+
PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
213+
for (PropertyDescriptor desc : descriptors) {
214+
if (!desc.getName().equals("class")) {
215+
entityFields.add(new EntityField(null, desc));
129216
}
130217
}
218+
return entityFields;
131219
}
132-
Class<?> superClass = entityClass.getSuperclass();
133-
if (superClass != null
134-
&& !superClass.equals(Object.class)
135-
&& (superClass.isAnnotationPresent(Entity.class)
136-
|| (!Map.class.isAssignableFrom(superClass)
137-
&& !Collection.class.isAssignableFrom(superClass)))) {
138-
return _getFields(entityClass.getSuperclass(), fieldList, ++level);
139-
}
140-
return fieldList;
141220
}
142221

143222
/**
144-
* 通过方法获取属性
145-
*
146-
* @param entityClass
147-
* @return
223+
* 支持jdk6,7
148224
*/
149-
private static List<EntityField> _getProperties(Class<?> entityClass) {
150-
List<EntityField> entityFields = new ArrayList<EntityField>();
151-
BeanInfo beanInfo = null;
152-
try {
153-
beanInfo = Introspector.getBeanInfo(entityClass);
154-
} catch (IntrospectionException e) {
155-
throw new RuntimeException(e);
225+
static class Jdk6_7FieldHelper implements IFieldHelper {
226+
227+
@Override
228+
public List<EntityField> getFields(Class<?> entityClass) {
229+
List<EntityField> fieldList = new ArrayList<EntityField>();
230+
_getFields(entityClass, fieldList, _getGenericTypeMap(entityClass), null);
231+
return fieldList;
232+
}
233+
234+
/**
235+
* 通过方法获取属性
236+
*
237+
* @param entityClass
238+
* @return
239+
*/
240+
public List<EntityField> getProperties(Class<?> entityClass) {
241+
Map<String, Class<?>> genericMap = _getGenericTypeMap(entityClass);
242+
List<EntityField> entityFields = new ArrayList<EntityField>();
243+
BeanInfo beanInfo;
244+
try {
245+
beanInfo = Introspector.getBeanInfo(entityClass);
246+
} catch (IntrospectionException e) {
247+
throw new RuntimeException(e);
248+
}
249+
PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
250+
for (PropertyDescriptor desc : descriptors) {
251+
if (desc != null && !"class".equals(desc.getName())) {
252+
EntityField entityField = new EntityField(null, desc);
253+
if (desc.getReadMethod() != null
254+
&& desc.getReadMethod().getGenericReturnType() != null
255+
&& desc.getReadMethod().getGenericReturnType() instanceof TypeVariable) {
256+
entityField.setJavaType(genericMap.get(((TypeVariable) desc.getReadMethod().getGenericReturnType()).getName()));
257+
} else if (desc.getWriteMethod() != null
258+
&& desc.getWriteMethod().getGenericParameterTypes() != null
259+
&& desc.getWriteMethod().getGenericParameterTypes().length == 1
260+
&& desc.getWriteMethod().getGenericParameterTypes()[0] instanceof TypeVariable) {
261+
entityField.setJavaType(genericMap.get(((TypeVariable) desc.getWriteMethod().getGenericParameterTypes()[0]).getName()));
262+
}
263+
entityFields.add(entityField);
264+
}
265+
}
266+
return entityFields;
156267
}
157-
PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
158-
for (PropertyDescriptor desc : descriptors) {
159-
if (!desc.getName().equals("class")) {
160-
entityFields.add(new EntityField(null, desc));
268+
269+
/**
270+
* @param entityClass
271+
* @param fieldList
272+
* @param genericMap
273+
* @param level
274+
*/
275+
private void _getFields(Class<?> entityClass, List<EntityField> fieldList, Map<String, Class<?>> genericMap, Integer level) {
276+
if (fieldList == null) {
277+
throw new NullPointerException("fieldList参数不能为空!");
278+
}
279+
if (level == null) {
280+
level = 0;
281+
}
282+
if (entityClass == Object.class) {
283+
return;
284+
}
285+
Field[] fields = entityClass.getDeclaredFields();
286+
int index = 0;
287+
for (Field field : fields) {
288+
if (!Modifier.isStatic(field.getModifiers())) {
289+
EntityField entityField = new EntityField(field, null);
290+
if (field.getGenericType() != null && field.getGenericType() instanceof TypeVariable) {
291+
if (genericMap == null || !genericMap.containsKey(((TypeVariable) field.getGenericType()).getName())) {
292+
throw new RuntimeException(entityClass + "字段" + field.getName() + "的泛型类型无法获取!");
293+
} else {
294+
entityField.setJavaType(genericMap.get(((TypeVariable) field.getGenericType()).getName()));
295+
}
296+
} else {
297+
entityField.setJavaType(field.getType());
298+
}
299+
if (level.intValue() != 0) {
300+
//将父类的字段放在前面
301+
fieldList.add(index, entityField);
302+
index++;
303+
} else {
304+
fieldList.add(entityField);
305+
}
306+
}
307+
}
308+
//获取父类和泛型信息
309+
Class<?> superClass = entityClass.getSuperclass();
310+
//判断superClass
311+
if (superClass != null
312+
&& !superClass.equals(Object.class)
313+
&& (superClass.isAnnotationPresent(Entity.class)
314+
|| (!Map.class.isAssignableFrom(superClass)
315+
&& !Collection.class.isAssignableFrom(superClass)))) {
316+
level++;
317+
_getFields(superClass, fieldList, genericMap, level);
318+
}
319+
}
320+
321+
/**
322+
* 获取所有泛型类型映射
323+
*
324+
* @param entityClass
325+
*/
326+
private Map<String, Class<?>> _getGenericTypeMap(Class<?> entityClass) {
327+
Map<String, Class<?>> genericMap = new HashMap<String, Class<?>>();
328+
if (entityClass == Object.class) {
329+
return genericMap;
330+
}
331+
//获取父类和泛型信息
332+
Class<?> superClass = entityClass.getSuperclass();
333+
//判断superClass
334+
if (superClass != null
335+
&& !superClass.equals(Object.class)
336+
&& (superClass.isAnnotationPresent(Entity.class)
337+
|| (!Map.class.isAssignableFrom(superClass)
338+
&& !Collection.class.isAssignableFrom(superClass)))) {
339+
if (entityClass.getGenericSuperclass() instanceof ParameterizedType) {
340+
Type[] types = ((ParameterizedType) entityClass.getGenericSuperclass()).getActualTypeArguments();
341+
TypeVariable[] typeVariables = superClass.getTypeParameters();
342+
if (typeVariables.length > 0) {
343+
for (int i = 0; i < typeVariables.length; i++) {
344+
if (types[i] instanceof Class) {
345+
genericMap.put(typeVariables[i].getName(), (Class<?>) types[i]);
346+
}
347+
}
348+
}
349+
}
350+
genericMap.putAll(_getGenericTypeMap(superClass));
161351
}
352+
return genericMap;
162353
}
163-
return entityFields;
164354
}
165355
}

0 commit comments

Comments
 (0)