/src/main/java/com/alibaba/fastjson/util/FieldInfo.java
https://bitbucket.org/xiejuntao/xdesktop · Java · 227 lines · 186 code · 41 blank · 0 comment · 56 complexity · 566d0c21c95bed87e5b1ea079087b834 MD5 · raw file
- package com.alibaba.fastjson.util;
- import java.lang.annotation.Annotation;
- import java.lang.reflect.Field;
- import java.lang.reflect.GenericDeclaration;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.lang.reflect.ParameterizedType;
- import java.lang.reflect.Type;
- import java.lang.reflect.TypeVariable;
- public class FieldInfo implements Comparable<FieldInfo> {
- private final String name;
- private final Method method;
- private final Field field;
- private final Class<?> fieldClass;
- private final Type fieldType;
- private final Class<?> declaringClass;
- private boolean getOnly = false;
- public FieldInfo(String name, Class<?> declaringClass, Class<?> fieldClass, Type fieldType, Method method,
- Field field){
- this.name = name;
- this.declaringClass = declaringClass;
- this.fieldClass = fieldClass;
- this.fieldType = fieldType;
- this.method = method;
- this.field = field;
- if (method != null) {
- method.setAccessible(true);
- }
- if (field != null) {
- field.setAccessible(true);
- }
- }
- public FieldInfo(String name, Method method, Field field){
- this(name, method, field, null, null);
- }
- public FieldInfo(String name, Method method, Field field, Class<?> clazz, Type type){
- this.name = name;
- this.method = method;
- this.field = field;
- if (method != null) {
- method.setAccessible(true);
- }
- if (field != null) {
- field.setAccessible(true);
- }
- Type fieldType;
- Class<?> fieldClass;
- if (method != null) {
- if (method.getParameterTypes().length == 1) {
- fieldClass = method.getParameterTypes()[0];
- fieldType = method.getGenericParameterTypes()[0];
- } else {
- fieldClass = method.getReturnType();
- fieldType = method.getGenericReturnType();
- getOnly = true;
- }
- this.declaringClass = method.getDeclaringClass();
- } else {
- fieldClass = field.getType();
- fieldType = field.getGenericType();
- this.declaringClass = field.getDeclaringClass();
- }
-
- if (clazz != null && fieldClass == Object.class && fieldType instanceof TypeVariable) {
- TypeVariable<?> tv = (TypeVariable<?>) fieldType;
- Type genericFieldType = getInheritGenericType(clazz, tv);
- if (genericFieldType != null) {
- this.fieldClass = TypeUtils.getClass(genericFieldType);
- this.fieldType = genericFieldType;
- return;
- }
- }
- Type genericFieldType = getFieldType(clazz, type, fieldType);
- if (genericFieldType != fieldType) {
- if (genericFieldType instanceof ParameterizedType) {
- fieldClass = TypeUtils.getClass(genericFieldType);
- } else if (genericFieldType instanceof Class) {
- fieldClass = TypeUtils.getClass(genericFieldType);
- }
- }
- this.fieldType = genericFieldType;
- this.fieldClass = fieldClass;
- }
- public static Type getFieldType(Class<?> clazz, Type type, Type fieldType) {
- if (clazz == null || type == null) {
- return fieldType;
- }
- if (!(type instanceof ParameterizedType)) {
- return fieldType;
- }
- if (fieldType instanceof TypeVariable) {
- ParameterizedType paramType = (ParameterizedType) type;
- TypeVariable<?> typeVar = (TypeVariable<?>) fieldType;
- for (int i = 0; i < clazz.getTypeParameters().length; ++i) {
- if (clazz.getTypeParameters()[i].getName().equals(typeVar.getName())) {
- fieldType = paramType.getActualTypeArguments()[i];
- break;
- }
- }
- }
- return fieldType;
- }
-
- public static Type getInheritGenericType(Class<?> clazz, TypeVariable<?> tv) {
- Type type = null;
- GenericDeclaration gd = tv.getGenericDeclaration();
- do {
- type = clazz.getGenericSuperclass();
- if (type == null) {
- return null;
- }
- if (type instanceof ParameterizedType) {
- ParameterizedType ptype = (ParameterizedType) type;
- if (ptype.getRawType() == gd) {
- TypeVariable<?>[] tvs = gd.getTypeParameters();
- Type[] types = ptype.getActualTypeArguments();
- for (int i = 0; i < tvs.length; i++) {
- if (tvs[i] == tv)
- return types[i];
- }
- return null;
- }
- }
- clazz = TypeUtils.getClass(type);
- } while (type != null);
- return null;
- }
- public String toString() {
- return this.name;
- }
- public Class<?> getDeclaringClass() {
- return declaringClass;
- }
- public Class<?> getFieldClass() {
- return fieldClass;
- }
- public Type getFieldType() {
- return fieldType;
- }
- public String getName() {
- return name;
- }
- public Method getMethod() {
- return method;
- }
- public Field getField() {
- return field;
- }
- public int compareTo(FieldInfo o) {
- return this.name.compareTo(o.name);
- }
- public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
- T annotation = null;
- if (method != null) {
- annotation = method.getAnnotation(annotationClass);
- }
- if (annotation == null) {
- if (field != null) {
- annotation = field.getAnnotation(annotationClass);
- }
- }
- return annotation;
- }
- public Object get(Object javaObject) throws IllegalAccessException, InvocationTargetException {
- if (method != null) {
- Object value = method.invoke(javaObject, new Object[0]);
- return value;
- }
- return field.get(javaObject);
- }
- public void set(Object javaObject, Object value) throws IllegalAccessException, InvocationTargetException {
- if (method != null) {
- method.invoke(javaObject, new Object[] { value });
- return;
- }
- field.set(javaObject, value);
- }
- public void setAccessible(boolean flag) throws SecurityException {
- if (method != null) {
- method.setAccessible(flag);
- return;
- }
- field.setAccessible(flag);
- }
- public boolean isGetOnly() {
- return getOnly;
- }
- }