下面列出了java.lang.reflect.Field#getType ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
*
* @param object
* The object which fields should be visited.
* @return {@code true} when the object was a observable object, {@code false} when it was a simple object.
* @throws SecurityException
* If a {@link SecurityManager} is active and denies access to fields via reflection.
* @throws IllegalAccessException
* If access modifiers like {@code private} are enforced even when the model is accessed via reflection.
*/
private boolean visitFields(final Object object) throws IllegalAccessException {
boolean isObservableObject = false;
for (final Field field : getInheritedFields(object.getClass())) {
field.setAccessible(true);
currentField = field;
final Class<?> fieldClass = field.getType();
if (!isObservableObject && classImplementsOrExtends(fieldClass, Property.class)) {
startVisiting(object);
isObservableObject = true;
}
if (classImplementsOrExtends(fieldClass, ListProperty.class)) {
handle((ListProperty<?>) field.get(object));
} else if (classImplementsOrExtends(fieldClass, SetProperty.class)) {
handle((SetProperty<?>) field.get(object));
} else if (classImplementsOrExtends(fieldClass, MapProperty.class)) {
handle((MapProperty<?, ?>) field.get(object));
} else if (classImplementsOrExtends(fieldClass, Property.class)) {
handle((Property<?>) field.get(object));
}
}
return isObservableObject;
}
/**
* Load game properties from the given game world object.
* @param xworld the world object.
*/
public void loadProperties(XElement xworld) {
try {
for (Field f : this.getClass().getDeclaredFields()) {
if (f.isAnnotationPresent(LoadSaveGame.class)) {
if (f.getType() == Boolean.TYPE) {
if (xworld.has(f.getName())) {
f.set(this, Boolean.valueOf(xworld.get(f.getName())));
}
} else
if (f.getType() == Integer.TYPE || f.getType() == Integer.class) {
if (xworld.has(f.getName())) {
f.set(this, Integer.valueOf(xworld.get(f.getName())));
}
} else
if (f.getType() == String.class) {
if (xworld.has(f.getName())) {
f.set(this, xworld.get(f.getName()));
}
}
}
}
} catch (IllegalAccessException ex) {
Exceptions.add(ex);
}
}
/**
* Check {@link FieldType} is validate to class type of {@link Field}.
*
* @param type the type
* @param field the field
*/
protected 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));
}
}
public static void injectWebServiceContext(final Object instance, final WebServiceContext ctx) {
final Class<?> instanceClass = instance.getClass();
//method injection not supported!
// inject @Resource
final Field[] resourceAnnotatedFields = instanceClass.getDeclaredFields();
for (Field field : resourceAnnotatedFields) {
try {
if (field.getDeclaredAnnotation(Resource.class) != null && field.getType() == WebServiceContext.class) {
setField(instance, field, ctx);
}
} catch (Exception e) {
throw new RuntimeException("Cannot inject @Resource annotated field: " + field, e);
}
}
}
@Override
protected Object getValue(Field field)
throws IllegalAccessException
{
if (field.getType() == String.class && field.isAnnotationPresent(SensitiveInfo.class) && maskFlag)
{
String value = (String)field.get(this.getObject());
switch (field.getAnnotation(SensitiveInfo.class).value())
{
case ID_CARD:
return SensitiveInfoUtils.idCard(value);
case ADDRESS:
return SensitiveInfoUtils.address(value, 6);
case MOBILE_PHONE:
return SensitiveInfoUtils.mobilePhone(value);
case EMAIL:
return SensitiveInfoUtils.email(value);
default:
return value;
}
}
return field.get(this.getObject());
}
public void classContentsIsEqualTo(
ImmutableMap<String, Integer> intFields,
ImmutableMap<String, List<Integer>> intArrayFields,
boolean areFieldsFinal) throws Exception {
String expectedClassName = actual;
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{basePath.toUri().toURL()});
Class<?> innerClass = urlClassLoader.loadClass(expectedClassName);
assertThat(innerClass.getSuperclass()).isEqualTo(Object.class);
assertThat(innerClass.getEnclosingClass().toString())
.endsWith(expectedClassName.substring(0, expectedClassName.indexOf('$')));
ImmutableMap.Builder<String, Integer> actualIntFields = ImmutableMap.builder();
ImmutableMap.Builder<String, List<Integer>> actualIntArrayFields = ImmutableMap.builder();
for (Field f : innerClass.getFields()) {
int fieldModifiers = f.getModifiers();
assertThat(Modifier.isFinal(fieldModifiers)).isEqualTo(areFieldsFinal);
assertThat(Modifier.isPublic(fieldModifiers)).isTrue();
assertThat(Modifier.isStatic(fieldModifiers)).isTrue();
Class<?> fieldType = f.getType();
if (fieldType.isPrimitive()) {
assertThat(fieldType).isEqualTo(Integer.TYPE);
actualIntFields.put(f.getName(), (Integer) f.get(null));
} else {
assertThat(fieldType.isArray()).isTrue();
int[] asArray = (int[]) f.get(null);
ImmutableList.Builder<Integer> list = ImmutableList.builder();
for (int i : asArray) {
list.add(i);
}
actualIntArrayFields.put(f.getName(), list.build());
}
}
assertThat(actualIntFields.build()).containsExactlyEntriesIn(intFields).inOrder();
assertThat(actualIntArrayFields.build()).containsExactlyEntriesIn(intArrayFields).inOrder();
}
public static void reload(FileConfiguration config) {
try {
for (Field field : Config.class.getFields()) {
Class<?> t = field.getType();
for (Parser parser : Parser.values()) {
if (t == parser.clazz) {
field.set(null, parser.function.apply(config, toKey(field.getName()), field.get(null)));
break;
}
}
config.set(toKey(field.getName()), field.get(null));
}
} catch (IllegalAccessException e) {
}
}
public static boolean isValidStringFieldType(Field field) {
if (BeanUtils.isCollectionType(field)) {
if (!BeanUtils.isValidCollectionType(field)) {
throw new IllegalArgumentException(
String.format("Unsupported list class type, name[%s].", field.getName()));
}
Class genericTypeClass = (Class) BeanUtils.getCollectionGenericType(field);
return String.class.isAssignableFrom(genericTypeClass);
}
Class<?> fieldClass = field.getType();
return String.class.isAssignableFrom(fieldClass);
}
/**
* 构建字段信息
* @param object
* @param fieldsMapping
* @return
*/
public static String buildFields(Object object, Map<String, String> fieldsMapping) throws IllegalAccessException {
Class clazz = object.getClass();
Field[] fields = clazz.getDeclaredFields();
StringBuilder fieldsBuilder = new StringBuilder("( ");
StringBuilder valuesBuilder = new StringBuilder("( ");
for(Field field : fields) {
field.setAccessible(true);
String fieldName = field.getName();
Object fieldValue = field.get(object);
//1. null 校验
if(null == fieldValue) {
continue;
}
Class fieldType = field.getType();
String tableFieldName = getTableFieldName(fieldName, fieldsMapping);
String fieldValueStr = getFieldValueStr(fieldType, fieldValue);
fieldsBuilder.append(tableFieldName).append(", ");
valuesBuilder.append("'").append(fieldValueStr).append("', ");
}
//2. 去掉多余的 ,
fieldsBuilder.deleteCharAt(fieldsBuilder.lastIndexOf(","));
valuesBuilder.deleteCharAt(valuesBuilder.lastIndexOf(","));
fieldsBuilder.append(" )");
valuesBuilder.append(" )");
return String.format("%s VALUES %s", fieldsBuilder.toString(), valuesBuilder.toString());
}
/**
* Checks if the provided field is a simple type field .
* @param field The field to check.
* @return True if the field has a simple type (see list in class comment) else false.
*/
public boolean isSimpleType(final Field field) {
Class< ? > type = field.getType();
boolean simpleType =
type.isAssignableFrom(Short.TYPE)
|| type.isAssignableFrom(Integer.TYPE)
|| type.isAssignableFrom(Float.TYPE)
|| type.isAssignableFrom(Double.TYPE)
|| type.isAssignableFrom(Long.TYPE)
|| type.isAssignableFrom(Byte.TYPE)
|| type.isAssignableFrom(Character.TYPE)
|| type.isAssignableFrom(Boolean.TYPE);
return simpleType;
}
/**
* Returns the class associated with the type annotation.
*/
private static Class<?> getDependencyClass(Field field) {
Type type = field.getGenericType();
if (type instanceof ParameterizedType) {
Type[] parameterizedTypes =
((ParameterizedType) field.getGenericType()).getActualTypeArguments();
Class<?> genericType = (Class) parameterizedTypes[parameterizedTypes.length - 1];
return genericType;
} else {
return field.getType();
}
}
/**
* Returns the name of the given code. Implementation of this method is inefficient,
* but it should rarely be invoked (mostly for formatting error messages).
*/
static String name(final short tag) {
try {
for (final Field field : GeoIdentifiers.class.getFields()) {
if (field.getType() == Short.TYPE) {
if (field.getShort(null) == tag) {
return field.getName();
}
}
}
} catch (IllegalAccessException e) {
throw new AssertionError(e); // Should never happen because we asked only for public fields.
}
return Integer.toHexString(Short.toUnsignedInt(tag));
}
/**
* Generates attributes dynamically for the fields declared in the given POJO class.
* <p/>
* Implementation is currently limited to generating attributes for Comparable fields (String, Integer etc.).
*
* @param pojoClass A POJO class
* @param <O> Type of the POJO class
* @return Attributes for fields in the POJO
*/
public static <O> Map<String, Attribute<O, Comparable>> generateAttributesForPojo(Class<O> pojoClass) {
Map<String, Attribute<O, Comparable>> generatedAttributes = new LinkedHashMap<String, Attribute<O, Comparable>>();
for (Field field : pojoClass.getDeclaredFields()) {
if (Comparable.class.isAssignableFrom(field.getType())) {
@SuppressWarnings({"unchecked"})
Class<Comparable> fieldType = (Class<Comparable>) field.getType();
generatedAttributes.put(field.getName(), ReflectiveAttribute.forField(pojoClass, fieldType, field.getName()));
}
}
return generatedAttributes;
}
public static boolean isValidDateType(Field field) {
if (BeanUtils.isCollectionType(field)) {
if (!BeanUtils.isValidCollectionType(field)) {
throw new IllegalArgumentException(
String.format("Unsupported list class type, name[%s].", field.getName()));
}
Class genericTypeClass = (Class) BeanUtils.getCollectionGenericType(field);
return Date.class.isAssignableFrom(genericTypeClass);
}
Class<?> fieldClass = field.getType();
return Date.class.isAssignableFrom(fieldClass);
}
private PriorityProperty<?> createPriorityProperty(Field field) {
String[] keys = collectPropertyKeys(field);
Class<?> fieldCls = field.getType();
switch (fieldCls.getName()) {
case "int":
return createIntProperty(field, keys, 0);
case "java.lang.Integer":
return createIntProperty(field, keys, null);
case "long":
return createLongProperty(field, keys, 0L);
case "java.lang.Long":
return createLongProperty(field, keys, null);
case "java.lang.String":
return createStringProperty(field, keys);
case "float":
return createFloatProperty(field, keys, 0f);
case "java.lang.Float":
return createFloatProperty(field, keys, null);
case "double":
return createDoubleProperty(field, keys, 0.0);
case "java.lang.Double":
return createDoubleProperty(field, keys, null);
case "boolean":
return createBooleanProperty(field, keys, false);
case "java.lang.Boolean":
return createBooleanProperty(field, keys, null);
}
throw new IllegalStateException("not support, field=" + field);
}
public ClassSizeInfo(final Class<?> clazz) {
long newFieldsSize = 0;
final List<Field> newReferenceFields = new LinkedList<>();
for (final Field f : clazz.getDeclaredFields()) {
if (Modifier.isStatic(f.getModifiers())) {
continue;
}
final Class<?> type = f.getType();
if (type.isPrimitive()) {
newFieldsSize += getPrimitiveFieldSize(type);
} else {
f.setAccessible(true);
newReferenceFields.add(f);
newFieldsSize += referenceSize;
}
}
final Class<?> superClass = clazz.getSuperclass();
if (superClass != null) {
final ClassSizeInfo superClassInfo = getClassSizeInfo(superClass);
newFieldsSize += roundTo(superClassInfo.fieldsSize, superclassFieldPadding);
newReferenceFields.addAll(Arrays.asList(superClassInfo.referenceFields));
}
this.fieldsSize = newFieldsSize;
this.objectSize = roundTo(objectHeaderSize + newFieldsSize, objectPadding);
this.referenceFields = newReferenceFields.toArray(
new Field[newReferenceFields.size()]);
}
AtomicIntegerFieldUpdaterImpl(final Class<T> tclass,
final String fieldName,
final Class<?> caller) {
final Field field;
final int modifiers;
try {
field = AccessController.doPrivileged(
new PrivilegedExceptionAction<Field>() {
public Field run() throws NoSuchFieldException {
return tclass.getDeclaredField(fieldName);
}
});
modifiers = field.getModifiers();
sun.reflect.misc.ReflectUtil.ensureMemberAccess(
caller, tclass, null, modifiers);
ClassLoader cl = tclass.getClassLoader();
ClassLoader ccl = caller.getClassLoader();
if ((ccl != null) && (ccl != cl) &&
((cl == null) || !isAncestor(cl, ccl))) {
sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
}
} catch (PrivilegedActionException pae) {
throw new RuntimeException(pae.getException());
} catch (Exception ex) {
throw new RuntimeException(ex);
}
if (field.getType() != int.class)
throw new IllegalArgumentException("Must be integer type");
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
// Access to protected field members is restricted to receivers only
// of the accessing class, or one of its subclasses, and the
// accessing class must in turn be a subclass (or package sibling)
// of the protected member's defining class.
// If the updater refers to a protected field of a declaring class
// outside the current package, the receiver argument will be
// narrowed to the type of the accessing class.
this.cclass = (Modifier.isProtected(modifiers) &&
tclass.isAssignableFrom(caller) &&
!isSamePackage(tclass, caller))
? caller : tclass;
this.tclass = tclass;
this.offset = U.objectFieldOffset(field);
}
public Tuple<Class, Object> toObject()
throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
String val = value;
String[] vals = val.split(":");
switch (type) {
case INT:
case INTEGER:
return new Tuple<>(Integer.class, Integer.parseInt(val));
case FLOAT:
return new Tuple<>(Float.class, Float.parseFloat(val));
case DOUBLE:
return new Tuple<>(Double.class, Double.parseDouble(val));
case BOOL:
case BOOLEAN:
return new Tuple<>(Boolean.class, Boolean.parseBoolean(val));
case BYTE:
return new Tuple<>(Byte.class, Byte.parseByte(val));
case CHAR:
return new Tuple<>(Character.class, val.charAt(0));
case LONG:
return new Tuple<>(Long.class, Long.parseLong(val));
case SHORT:
return new Tuple<>(Short.class, Short.parseShort(val));
case STRING:
return new Tuple<>(String.class, val);
case CLASS:
return new Tuple<>(Class.class, Class.forName(val));
case ENUM:
Class clazz = Class.forName(vals[0]);
return new Tuple<Class, Object>(clazz, Enum.valueOf(clazz, vals[1]));
case VECTOR3D:
return new Tuple<>(Vector3d.class, new Vector3d(
Double.parseDouble(vals[0]), Double.parseDouble(vals[1]), Double.parseDouble(vals[2])));
case VECTOR3I:
return new Tuple<>(Vector3i.class, new Vector3i(
Integer.parseInt(vals[0]), Integer.parseInt(vals[1]), Integer.parseInt(vals[2])));
case TEXT:
return new Tuple<>(Text.class, Text.of(val));
case WORLD:
Optional<World> w = Sponge.getServer().getWorld(UUID.fromString(val));
return new Tuple<>(World.class, w.orElse(null));
case PLAYER:
Optional<Player> p = Sponge.getServer().getPlayer(UUID.fromString(val));
return new Tuple<>(Player.class, p.orElse(null));
case ITEMSTACK:
Optional<ItemType> t = Sponge.getRegistry().getType(ItemType.class, vals[0]);
if (!t.isPresent())
throw new ClassNotFoundException(vals[0]);
return new Tuple<>(ItemStack.class, ItemStack.of(t.get(), Integer.parseInt(vals[1])));
case STATIC:
Class c = Class.forName(vals[0]);
Field f = c.getField(vals[1]);
return new Tuple<>(f.getType(), f.get(null));
default:
return null;
}
}
/**
*
* 对象的大小
*
* @param object
*
* @return 对象的大小
*/
private int sizeof0(Object object) {
if (object == null) {
return 0;
}
Class<?> clazz = object.getClass();
if (!clazz.isPrimitive()) {
identityMap.put(object, null);
}
int size = EMPTY_OBJECT_SIZE;
if (clazz.isArray()) {
return sizeofArray(clazz, object, size);
}
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (Modifier.isStatic(field.getModifiers())) {
continue;// 类成员不计
}
Class<?> type = field.getType();
if (type.isPrimitive())
size += sizeofPrimitiveClass(type);
else {
size += 4;// 一个引用型变量占用4个字节
try {
field.setAccessible(true);// 可以访问非public类型的变量
// FIXME 存在死循环,fixed
Object value = field.get(object);
if (value != null && !identityMap.containsKey(value)) {
identityMap.put(value, null);
size += sizeof0(value);
}
} catch (Exception e) {
size += sizeofConstructor(object, field);
}
}
}
return size;
}
/**
* Judge a field is a primitive boolean type or not. Cause it's a little
* special when use IDE to generate getter and setter method. The primitive
* boolean type won't be like <b>getXxx</b>, it's something like
* <b>isXxx</b>.
*
* @param field
* Use field to get field type.
* @return If it's primitive boolean type return true, else return false.
*/
private boolean isPrimitiveBooleanType(Field field) {
Class<?> fieldType = field.getType();
if ("boolean".equals(fieldType.getName())) {
return true;
}
return false;
}