下面列出了java.lang.reflect.Field#getGenericType ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
protected boolean isDecoratableList(Field field) {
if (!List.class.isAssignableFrom(field.getType())) {
return false;
}
// Type erasure in Java isn't complete. Attempt to discover the generic
// type of the list.
Type genericType = field.getGenericType();
if (!(genericType instanceof ParameterizedType)) {
return false;
}
Type listType = ((ParameterizedType) genericType).getActualTypeArguments()[0];
if (!WebElement.class.equals(listType)) {
return false;
}
return field.getAnnotation(FindBy.class) != null ||
field.getAnnotation(FindBys.class) != null ||
field.getAnnotation(FindAll.class) != null;
}
/**
* 获取字段的泛型类型, 如果不带泛型返回 null
* @param field {@link Field}
* @param <?> 未知类型
* @return 泛型类型
*/
public static Class<?> getGenericType(final Field field) {
if (field == null) return null;
try {
Type type = field.getGenericType();
if (type instanceof ParameterizedType) {
type = ((ParameterizedType) type).getActualTypeArguments()[0];
if (type instanceof Class<?>) {
return (Class<?>) type;
}
} else if (type instanceof Class<?>) {
return (Class<?>) type;
}
} catch (Exception e) {
JCLogUtils.eTag(TAG, e, "getGenericType");
}
return null;
}
@SuppressWarnings("unchecked")
private boolean isDecoratable(Field field) {
if (!hasAnnotation(field, com.qmetry.qaf.automation.ui.annotations.FindBy.class, FindBy.class, FindBys.class)) {
return false;
}
if (WebElement.class.isAssignableFrom(field.getType())) {
return true;
}
if (!(List.class.isAssignableFrom(field.getType()))) {
return false;
}
Type genericType = field.getGenericType();
if (!(genericType instanceof ParameterizedType)) {
return false;
}
Type listType = ((ParameterizedType) genericType).getActualTypeArguments()[0];
return WebElement.class.isAssignableFrom((Class<?>) listType);
}
public static boolean isFieldPrintable(Field field)
{
boolean isPrintable = false;
Type fieldType = field.getGenericType();
if (fieldType instanceof ParameterizedType)
{
Type[] declaredGenericTypes = ((ParameterizedType) fieldType).getActualTypeArguments();
for (Type type : declaredGenericTypes)
{
isPrintable = ClassTypeHelper.isPrintableClass((Class<?>) type);
if (!isPrintable)
{
break;
}
}
}
return isPrintable;
}
/**
* The name of the dimension as stated in the ChannelType configuration.
* e.g.
* <p>
* <code> Unit: 'm' -> "Length"</code>
* <p>
* <code> Unit: 'kWh' -> "Energy"</code>
* <p>
* If the {@link Unit} can not be found in any of the available Measurement systems, it returns <code>null</code>
*
* @param unit The {@link Unit} to get the Dimension's name from.
* @return The Dimension string or null if the unit can not be found in any of the SystemOfUnits.
*/
public static @Nullable String getDimensionName(Unit<?> unit) {
for (Class<? extends SystemOfUnits> system : ALL_SYSTEM_OF_UNITS) {
for (Field field : system.getDeclaredFields()) {
if (field.getType().isAssignableFrom(Unit.class) && Modifier.isStatic(field.getModifiers())) {
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType) {
String dimension = ((Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[0])
.getSimpleName();
Unit<?> systemUnit;
try {
systemUnit = (Unit<?>) field.get(null);
if (systemUnit == null) {
LOGGER.warn("Unit field points to a null value: {}", field);
} else if (systemUnit.isCompatible(unit)) {
return dimension;
}
} catch (IllegalArgumentException | IllegalAccessException e) {
LOGGER.error("The unit field '{}' seems to be not accessible", field, e);
}
} else {
LOGGER.warn("There is a unit field defined which has no generic type parametrization: {}",
field);
}
}
}
}
return null;
}
private <T> void mapFields(T instance, Class<T> clazz, String path, String name, Map<String, String> propertyNames, Config config) {
try {
for (FieldDescriptor descriptor : getFieldDescriptors(instance.getClass())) {
Field field = descriptor.field;
field.setAccessible(true);
Type genericType = field.getGenericType();
Class<?> fieldClass = field.getType();
String configPropName = propertyNames.remove(descriptor.name);
if (configPropName == null) {
if (Named.class.isAssignableFrom(clazz) && field.getType() == String.class && name != null && "name".equals(descriptor.name)) {
if (descriptor.deprecated) {
LOGGER.warn("{}.{} is deprecated!", path, name);
}
field.set(instance, name);
}
continue;
}
Object value = getValue(instance.getClass(), genericType, fieldClass, config, toPath(path, name), configPropName);
if (value != null) {
if (descriptor.deprecated) {
LOGGER.warn("{}.{} is deprecated!", path, name);
}
field.set(instance, value);
}
}
} catch (IllegalAccessException e) {
throw new ConfigurationException(instance.getClass().getName() + " fields are not accessible, they must be for use as a bean", e);
}
}
/**
* Finds the generic type (parametrized type) of the field. If the field is not generic it returns Object.class.
*
* @param field
*/
public Class getGenericType(Field field) {
Type generic = field.getGenericType();
if (generic != null && generic instanceof ParameterizedType) {
Type actual = ((ParameterizedType) generic).getActualTypeArguments()[0];
if (actual instanceof Class) {
return (Class) actual;
} else if (actual instanceof ParameterizedType) {
//in case of nested generics we don't go deep
return (Class) ((ParameterizedType) actual).getRawType();
}
}
return Object.class;
}
public static Type getPortType(Field f)
{
if (f.getGenericType() instanceof ParameterizedType) {
ParameterizedType t = (ParameterizedType)f.getGenericType();
//LOG.debug("Field type is parameterized: " + Arrays.asList(t.getActualTypeArguments()));
//LOG.debug("rawType: " + t.getRawType()); // the port class
Type typeArgument = t.getActualTypeArguments()[0];
if (typeArgument instanceof Class) {
return typeArgument;
} else if (typeArgument instanceof TypeVariable) {
TypeVariable<?> tv = (TypeVariable<?>)typeArgument;
LOG.debug("bounds: {}", Arrays.asList(tv.getBounds()));
// variable may contain other variables, java.util.Map<java.lang.String, ? extends T2>
return tv.getBounds()[0];
} else if (typeArgument instanceof GenericArrayType) {
LOG.debug("type {} is of GenericArrayType", typeArgument);
return typeArgument;
} else if (typeArgument instanceof WildcardType) {
LOG.debug("type {} is of WildcardType", typeArgument);
return typeArgument;
} else if (typeArgument instanceof ParameterizedType) {
return typeArgument;
} else {
LOG.error("Type argument is of expected type {}", typeArgument);
return null;
}
} else {
// ports are always parameterized
LOG.error("No type variable: {}, typeParameters: {}", f.getType(), Arrays.asList(f.getClass().getTypeParameters()));
return null;
}
}
/**
* 获取域的泛型类型,如果不带泛型返回null
*
* @param f
* @return
*/
public static Class<?> getGenericType(Field f) {
Type type = f.getGenericType();
if (type instanceof ParameterizedType) {
type = ((ParameterizedType) type).getActualTypeArguments()[0];
if (type instanceof Class<?>) return (Class<?>) type;
} else if (type instanceof Class<?>) return (Class<?>) type;
return null;
}
private boolean isFieldCollectionOfCssNode(Field field) {
// There are two ways in which this field can be a collection of CssNodes:
// it can be something like Collection<SomethingThatExtendsCssNode>,
// or it can be a variable type like Collection<T extends CssNode>.
if (Collection.class.isAssignableFrom(field.getType())
&& field.getGenericType() instanceof ParameterizedType) {
ParameterizedType collectionType =
(ParameterizedType) field.getGenericType();
for (Type type : collectionType.getActualTypeArguments()) {
// This is a type that inherits from CssNode.
if (type instanceof Class
&& CssNode.class.isAssignableFrom((Class<?>) type)) {
return true;
}
// Type is a variable type that extends CssNode.
if (type instanceof TypeVariable) {
for (Type t : ((TypeVariable<?>) type).getBounds()) {
if (t instanceof Class
&& CssNode.class.isAssignableFrom((Class<?>) t)) {
return true;
}
}
}
}
}
return false;
}
private static void fetchRefList(BuguEntity obj, Field field){
Object val = FieldUtil.get(obj, field);
if(val == null){
return;
}
Class<?> type = field.getType();
if(type.isArray()){
Object arr = fetchArrayValue(val, field, type.getComponentType());
FieldUtil.set(obj, field, arr);
}else{
ParameterizedType paramType = (ParameterizedType)field.getGenericType();
Type[] types = paramType.getActualTypeArguments();
int len = types.length;
if(len == 1){
//for Collection
List list = fetchCollectionValue(val, field, (Class)types[0]);
if(DataType.isListType(type)){
FieldUtil.set(obj, field, list);
}
else if(DataType.isSetType(type)){
FieldUtil.set(obj, field, new HashSet(list));
}
else if(DataType.isQueueType(type)){
FieldUtil.set(obj, field, new LinkedList(list));
}
}else if(len == 2){
//for Map
Map map = fetchMapValue(val, field);
FieldUtil.set(obj, field, map);
}
}
}
private static <T> T parserToObject(Class<T> c, Node node, boolean useAnnotation) throws XMLParserException {
if (null == node) {
return null;
}
T t = null;
try {
final Constructor constructor = c.getDeclaredConstructor();
constructor.setAccessible(true);
t = (T) constructor.newInstance();
final Field[] fields = c.getDeclaredFields();
String filedName = null;
for (final Field field : fields) {
field.setAccessible(true);
if (field.isEnumConstant() || Modifier.isFinal(field.getModifiers())) {
continue;
}
filedName = getFieldName(field, useAnnotation);
if (!List.class.isAssignableFrom(field.getType())) {
setField(t, field, node, useAnnotation, filedName);
} else {
if (field.getGenericType() instanceof ParameterizedType) {
final ParameterizedType pt = (ParameterizedType) field.getGenericType();
final Class<?> genericClazz = (Class<?>) pt.getActualTypeArguments()[0];
final List<?> list = parserToList(genericClazz, getNodeList(node, filedName), useAnnotation);
field.set(t, list);
} else {
Log.i(TAG, field.getName() + " require have generic");
}
}
}
} catch (Exception e) {
throw new XMLParserException(c, "constructor is not accessible,must have zero-argument constructor", e);
}
return t;
}
public static boolean isReferencedFieldType(Field targetField) {
if (Collection.class.isAssignableFrom(targetField.getType())) {
ParameterizedType listType = (ParameterizedType) targetField.getGenericType();
Class<?> type = (Class<?>) listType.getActualTypeArguments()[0];
if (type.getAnnotation(ReferencedRecord.class) != null) {
return true;
}
}
return false;
}
public ProtobufField(Field field) {
annotation = field.getAnnotation(Protobuf.class);
name = field.getName();
type = field.getType();
declaredClass = field.getDeclaringClass();
genericType = field.getGenericType();
}
protected Class<?> deriveFieldType(Field field, Map<String, Class<?>> genericMap) {
final Class<?> fieldType;
final Type genericType = field.getGenericType();
if (genericType != null && !genericMap.isEmpty()) { // e.g. public HAUNTED haunted;
final Class<?> translatedType = genericMap.get(genericType.getTypeName()); // e.g. PiariBean by HAUNTED
fieldType = translatedType != null ? translatedType : field.getType();
} else {
fieldType = field.getType();
}
return fieldType;
}
/**
* Test of getParametrizedType method, of class ReflectionUtil.
* @throws java.lang.Exception
*/
@Test
public void testGetParametrizedType() throws Exception {
Field stringListField = this.getClass().getDeclaredField("reflectable");
ParameterizedType genericListType = (ParameterizedType) stringListField.getGenericType();
assertThat(ReflectionUtil.getParametrizedType(reflectable.getClass()).toString()).isEqualTo(genericListType.toString());
assertThat(ReflectionUtil.getParametrizedType(multi.getClass()).getRawType().getTypeName()).isEqualTo(First.class.getName());
assertThat(ReflectionUtil.getParametrizedType(Object.class)).isNull();
}
public boolean load() {
if (!this.configFile.exists()) return false;
Config cfg = new Config(configFile, Config.YAML);
for (Field field : this.getClass().getDeclaredFields()) {
if (field.getName().equals("configFile")) continue;
if (skipSave(field)) continue;
String path = getPath(field);
if (path == null) continue;
if (path.isEmpty()) continue;
field.setAccessible(true);
try {
if (field.getType() == int.class || field.getType() == Integer.class)
field.set(this, cfg.getInt(path, field.getInt(this)));
else if (field.getType() == boolean.class || field.getType() == Boolean.class)
field.set(this, cfg.getBoolean(path, field.getBoolean(this)));
else if (field.getType() == long.class || field.getType() == Long.class)
field.set(this, cfg.getLong(path, field.getLong(this)));
else if (field.getType() == double.class || field.getType() == Double.class)
field.set(this, cfg.getDouble(path, field.getDouble(this)));
else if (field.getType() == String.class)
field.set(this, cfg.getString(path, (String) field.get(this)));
else if (field.getType() == ConfigSection.class)
field.set(this, cfg.getSection(path));
else if (field.getType() == List.class) {
Type genericFieldType = field.getGenericType();
if (genericFieldType instanceof ParameterizedType) {
ParameterizedType aType = (ParameterizedType) genericFieldType;
Class fieldArgClass = (Class) aType.getActualTypeArguments()[0];
if (fieldArgClass == Integer.class) field.set(this, cfg.getIntegerList(path));
else if (fieldArgClass == Boolean.class) field.set(this, cfg.getBooleanList(path));
else if (fieldArgClass == Double.class) field.set(this, cfg.getDoubleList(path));
else if (fieldArgClass == Character.class) field.set(this, cfg.getCharacterList(path));
else if (fieldArgClass == Byte.class) field.set(this, cfg.getByteList(path));
else if (fieldArgClass == Float.class) field.set(this, cfg.getFloatList(path));
else if (fieldArgClass == Short.class) field.set(this, cfg.getFloatList(path));
else if (fieldArgClass == String.class) field.set(this, cfg.getStringList(path));
} else field.set(this, cfg.getList(path)); // Hell knows what's kind of List was found :)
} else
throw new IllegalStateException("SimpleConfig did not supports class: " + field.getType().getName() + " for config field " + configFile.getName());
} catch (Exception e) {
Server.getInstance().getLogger().logException(e);
return false;
}
}
return true;
}
@SuppressWarnings("unchecked")
private static void setBundleValue(@NonNull Field field, @NonNull Object obj,
@NonNull Bundle bundle, @NonNull String key, boolean isGson)
throws IllegalAccessException {
if (isGson) {
bundle.putString(key, GsonHelper.toJson(field.get(obj)));
return;
}
Class<?> type = field.getType();
Type[] genericTypes = null;
if (field.getGenericType() instanceof ParameterizedType) {
genericTypes = ((ParameterizedType) field.getGenericType()).getActualTypeArguments();
}
if (type.equals(Boolean.TYPE)) {
bundle.putBoolean(key, field.getBoolean(obj));
} else if (type.equals(boolean[].class)) {
bundle.putBooleanArray(key, (boolean[]) field.get(obj));
} else if (type.equals(Bundle.class)) {
bundle.putBundle(key, (Bundle) field.get(obj));
} else if (type.equals(Byte.TYPE)) {
bundle.putByte(key, field.getByte(obj));
} else if (type.equals(byte[].class)) {
bundle.putByteArray(key, (byte[]) field.get(obj));
} else if (type.equals(Character.TYPE)) {
bundle.putChar(key, field.getChar(obj));
} else if (type.equals(char[].class)) {
bundle.putCharArray(key, (char[]) field.get(obj));
} else if (type.equals(CharSequence.class)) {
bundle.putCharSequence(key, (CharSequence) field.get(obj));
} else if (type.equals(CharSequence[].class)) {
bundle.putCharSequenceArray(key, (CharSequence[]) field.get(obj));
} else if (type.equals(Double.TYPE)) {
bundle.putDouble(key, field.getDouble(obj));
} else if (type.equals(double[].class)) {
bundle.putDoubleArray(key, (double[]) field.get(obj));
} else if (type.equals(Float.TYPE)) {
bundle.putFloat(key, field.getFloat(obj));
} else if (type.equals(float[].class)) {
bundle.putFloatArray(key, (float[]) field.get(obj));
} else if (type.equals(Integer.TYPE)) {
bundle.putInt(key, field.getInt(obj));
} else if (type.equals(int[].class)) {
bundle.putIntArray(key, (int[]) field.get(obj));
} else if (type.equals(Long.TYPE)) {
bundle.putLong(key, field.getLong(obj));
} else if (type.equals(long[].class)) {
bundle.putLongArray(key, (long[]) field.get(obj));
} else if (type.equals(Short.TYPE)) {
bundle.putShort(key, field.getShort(obj));
} else if (type.equals(short[].class)) {
bundle.putShortArray(key, (short[]) field.get(obj));
} else if (type.equals(String.class)) {
bundle.putString(key, (String) field.get(obj));
} else if (type.equals(String[].class)) {
bundle.putStringArray(key, (String[]) field.get(obj));
} else if (Parcelable.class.isAssignableFrom(type)) {
bundle.putParcelable(key, (Parcelable) field.get(obj));
} else if (type.equals(ArrayList.class)
&& genericTypes != null
&& genericTypes[0] instanceof Class
&& Parcelable.class.isAssignableFrom((Class<?>) genericTypes[0])) {
bundle.putParcelableArrayList(key, (ArrayList<? extends Parcelable>) field.get(obj));
} else if (type.isArray() && Parcelable.class.isAssignableFrom(type.getComponentType())) {
bundle.putParcelableArray(key, (Parcelable[]) field.get(obj));
} else if (Serializable.class.isAssignableFrom(type)) {
bundle.putSerializable(key, (Serializable) field.get(obj));
} else {
throw new RuntimeException("Unsupported field type: " + field.getName()
+ ", " + type.getName());
}
}
public static Class<?> getTypeOfList(Field field) {
ParameterizedType stringListType = (ParameterizedType) field.getGenericType();
Class<?> elementClass = (Class<?>) stringListType.getActualTypeArguments()[0];
return elementClass;
}
public List<ResultMapping> resolveResultMappings(String resource, String id, Class<?> type) {
List<ResultMapping> resultMappings = new ArrayList<>();
MapperBuilderAssistant assistant = new MapperBuilderAssistant(configuration, resource);
List<Field> fields = PersistentUtil.getPersistentFields(type);
for (Field field : fields) {
// java field name
String property = field.getName();
// sql column name
String column = PersistentUtil.getColumnName(field);
Class<?> javaType = field.getType();
//resultMap is not need jdbcType
JdbcType jdbcType = null;
String nestedSelect = null;
String nestedResultMap = null;
if (PersistentUtil.isAssociationField(field)) {
// OneToOne or OneToMany
// mappedBy
column = PersistentUtil.getMappedName(field);
if (field.isAnnotationPresent(OneToOne.class)) {
nestedResultMap = id + "_association[" + javaType.getSimpleName() + "]";
registerResultMap(resolveResultMap(resource, nestedResultMap, javaType));
}
if (field.isAnnotationPresent(OneToMany.class)) {
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) genericType;
Class<?> actualType = (Class<?>) pt.getActualTypeArguments()[0];
// create resultMap with actualType
nestedResultMap = id + "collection[" + actualType.getSimpleName() + "]";
registerResultMap(resolveResultMap(resource, nestedResultMap, actualType));
}
}
}
String notNullColumn = null;
String columnPrefix = null;
String resultSet = null;
String foreignColumn = null;
// if primaryKey,then flags.add(ResultFlag.ID);
List<ResultFlag> flags = new ArrayList<>();
if (field.isAnnotationPresent(Id.class)) {
flags.add(ResultFlag.ID);
}
// lazy or eager
boolean lazy = false;
// typeHandler
Class<? extends TypeHandler<?>> typeHandlerClass = ColumnMetaResolver
.resolveTypeHandler(field);
ResultMapping resultMapping = assistant.buildResultMapping(type, property, column,
javaType, jdbcType, nestedSelect, nestedResultMap, notNullColumn, columnPrefix,
typeHandlerClass, flags, resultSet, foreignColumn, lazy);
resultMappings.add(resultMapping);
}
return resultMappings;
}