获取字段对应的Type类型<br>
方法优先获取GenericType，获取不到则获取Type

@param field 字段
@return {@link Type}，可能为{@code null}
329472
public static Type getType(Field field) {
		if (null == field) {
			return null;
		}
		Type type = field.getGenericType();
		if (null == type) {
			type = field.getType();
		}
		return type;
	}
408520
public Object get(String field) {
        if (target == null) {
            return null;
        }

        return get(field, field, target);
    }
698913
public static <T extends FieldDescription> ElementMatcher.Junction<T> genericFieldType(Type fieldType) {
        return genericFieldType(TypeDefinition.Sort.describe(fieldType));
    }
16115
private void determineFieldType(Field field) {
        // Determine the class of data stored in the field
        Class<?> fieldType = field.getType();

        isCollection = Collection.class.isAssignableFrom(fieldType);

        valueClass=null;
        if (!isCollection) {
            // It's not a list so assume its single valued - so just take the field type
            valueClass = fieldType;
        } else {
            determineCollectionClass(fieldType);
            // It's multi-valued - so we need to look at the signature in
            // the class file to find the generic type - this is supported for class file
            // format 49 and greater which corresponds to java 5 and later.
            ParameterizedType paramType;
            try {
                paramType = (ParameterizedType)field.getGenericType();
            } catch (ClassCastException e) {
                throw new MetaDataException(String.format("Can't determine destination type for field %1$s in Entry class %2$s", 
                        field, field.getDeclaringClass()), e);
            }
            Type[] actualParamArguments = paramType.getActualTypeArguments();
            if (actualParamArguments.length == 1) {
                if (actualParamArguments[0] instanceof Class) {
                    valueClass = (Class<?>)actualParamArguments[0];                    
                } else {
                    if (actualParamArguments[0] instanceof GenericArrayType) {
                        // Deal with arrays
                        Type type=((GenericArrayType)actualParamArguments[0]).getGenericComponentType();
                        if (type instanceof Class) {
                            valueClass=Array.newInstance((Class<?>)type, 0).getClass();
                        } 
                    } 
                }
            } 
        }

        // Check we have been able to determine the value class
        if (valueClass==null) {
            throw new MetaDataException(String.format("Can't determine destination type for field %1$s in class %2$s", 
                    field, field.getDeclaringClass()));
        }
    }
702416
private void primitiveGetter(Field field) {
    String typeName = field.getType().getName();
    String methodName = String.format("get%c%s", Character.toUpperCase(typeName.charAt(0)), typeName.substring(1));

    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, getMethod(field.getType(), methodName, Object.class),
                                               null, new Type[0], classWriter);
    if (isPrivate) {
      // get the value using the generic Object get(Object) method and unbox the value
      mg.loadThis();
      mg.loadArg(0);
      mg.invokeVirtual(Type.getObjectType(className), getMethod(Object.class, "get", Object.class));
      mg.unbox(Type.getType(field.getType()));
    } else {
      // Simply access the field.
      mg.loadArg(0);
      mg.checkCast(Type.getType(field.getDeclaringClass()));
      mg.getField(Type.getType(field.getDeclaringClass()), field.getName(), Type.getType(field.getType()));
    }
    mg.returnValue();
    mg.endMethod();
  }
208530
public static Type getPropertyType(Class<?> beanClass, String field) {
        try {
            return INSTANCE.findPropertyType(beanClass, field);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw handleReflectionException(beanClass, field, e);
        }
    }
521401
public static SoyValue getProtoField(SoyProtoValue proto, String field) {
    if (proto == null) {
      throw new NullPointerException("Attempted to access field '" + field + "' of null");
    }
    return handleTofuNull(proto.getProtoField(field));
  }
692951
@SuppressWarnings("unchecked")
	public <T> T getOne(String field) {
		return (T) get(field).get(field);
	}
374675
public static Class getFieldType(FieldNode field) {
        // Step 1: Analyze the field's declared type
        Class declaredType = getClassForClassNode(field.getType());
        if (declaredType != null) {
            return declaredType;
        }

        // Step 2: Analyze the cast type of the initial expression
        if (field.getInitialExpression() != null) {
            Class castType = getClassForClassNode(field.getInitialExpression().getType());
            if (castType != null) {
                return castType;
            }
        }

        // Step 3: Look at the literal within the constant
        if (field.getInitialExpression() instanceof ConstantExpression) {
            Object constantValue = ((ConstantExpression) field.getInitialExpression()).getValue();
            if (constantValue == null) {
                return null;
            } else if (constantValue instanceof String) {
                return String.class;
            } else if (isBoolean(field.getInitialExpression())) {
                return Boolean.class;
            } else if (constantValue.getClass() == Integer.class || constantValue.getClass() == Integer.TYPE) {
                return Integer.class;
            } else if (constantValue.getClass() == Long.class || constantValue.getClass() == Long.TYPE) {
                return Long.class;
            } else if (constantValue.getClass() == Double.class || constantValue.getClass() == Double.TYPE) {
                return Double.class;
            } else if (constantValue.getClass() == Float.class || constantValue.getClass() == Float.TYPE) {
                return Float.class;
            }
        }
        return null;
    }
195214
@Override
    public Type getType() {
        ParameterizedType type = (ParameterizedType) field.getGenericType();
        if (type.getActualTypeArguments()[0] instanceof ParameterizedType) {
            ParameterizedType first = (ParameterizedType) type.getActualTypeArguments()[0];
            return first.getRawType();
        } else {
            return type.getActualTypeArguments()[0];
        }
    }
621775
private PropDesc createProp(Field field) {
		final String fieldName = field.getName();
		final Class<?> fieldType = field.getType();
		final boolean isBooeanField = BooleanUtil.isBoolean(fieldType);

		Method getter = null;
		Method setter = null;

		String methodName;
		Class<?>[] parameterTypes;
		for (Method method : ReflectUtil.getMethods(this.beanClass)) {
			parameterTypes = method.getParameterTypes();
			if (parameterTypes.length > 1) {
				// 多于1个参数说明非Getter或Setter
				continue;
			}

			methodName = method.getName();
			if (parameterTypes.length == 0) {
				// 无参数，可能为Getter方法
				if (isMatchGetter(methodName, fieldName, isBooeanField)) {
					// 方法名与字段名匹配，则为Getter方法
					getter = method;
				}
			} else if (isMatchSetter(methodName, fieldName, isBooeanField)) {
				// 只有一个参数的情况下方法名与字段名对应匹配，则为Setter方法
				setter = method;
			}
			if (null != getter && null != setter) {
				// 如果Getter和Setter方法都找到了，不再继续寻找
				break;
			}
		}
		return new PropDesc(field, getter, setter);
	}
563477
private void checkType(FieldType type, Field field) {
        Class<?> cls = field.getType();

        if (type == FieldType.OBJECT || type == FieldType.ENUM) {
            return;
        }

        String javaType = type.getJavaType();
        if (Integer.class.getSimpleName().equals(javaType)) {
            if (cls.getSimpleName().equals("int") || Integer.class.getSimpleName().equals(cls.getSimpleName())) {
                return;
            }
            throw new IllegalArgumentException(getMismatchTypeErroMessage(type, field));
        }
        if (!javaType.equalsIgnoreCase(cls.getSimpleName())) {
            throw new IllegalArgumentException(getMismatchTypeErroMessage(type, field));
        }
    }
1019643
private BeanSpec beanSpecOf(Field field, Type genericType) {
        return of(field, genericType, injector);
//        int len = typeArgs.size();
//        for (int i = 0; i < len; ++i) {
//            if (genericType.equals(typeArgs.get(i))) {
//                return of(field, typeImpls.get(i), injector());
//            }
//        }
//        return of(field, injector);
    }
636946
public static ResolvableType forField(Field field) {
		Assert.notNull(field, "Field must not be null");
		return forType(null, new FieldTypeProvider(field), null);
	}
115935
public static Type forField(Field field) {
		Assert.notNull(field, "Field must not be null");
		return forTypeProvider(new FieldTypeProvider(field));
	}
840265
public static Class<?> getGenericTypeArgument(Field field) {
        // TODO Might this better be located under SPI in an "InjectionUtil" class or something?
        Type genericType = field.getGenericType();
        if (genericType instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) genericType;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            if (actualTypeArguments.length == 1) {
                Type type = actualTypeArguments[0];
                if (type instanceof Class<?>) {
                    Class<?> realClass = (Class<?>) type;
                    return realClass;
                } else {
                    throw new IllegalArgumentException(
                        "only direct class types are allowed for generic parameter on field " + field.getName()
                                + " of type "
                                + genericType.getClass().getName() + "<T>, but " + type
                                + " was given!");
                }
            } else {
                throw new IllegalArgumentException("only one type parameter expected for field " + field.getName()
                        + " but " + actualTypeArguments.length
                        + " where found!");
            }
        } else {
            throw new IllegalArgumentException(
                "The field '" + field.getName()
                        + "' is not a ParameterizedType but this is required for type inferrence!");
        }
    }
664787
public static <T> T getField(Object obj, String string, Class<?> clazz, Class<T> fieldType) {
		try {
			final Field field = clazz.getDeclaredField(string);
			field.setAccessible(true);
			final Object value = field.get(obj);
			return fieldType.cast(value);
		} catch (Exception exception) {
			throw new Error(exception);
		}
	}