代码有这样的需求, 要求在运行时利用java反射机制获取泛型类的参数类对象,
例如
class Family
{
List
}
希望用反射得到类似Person.class的类对象.
如果是非泛型的字段, 例如 Person father; 则用Field.getType()方法即可:
/**
* Returns a {@code Class} object that identifies the
* declared type for the field represented by this
* {@code Field} object.
*
* @return a {@code Class} object identifying the declared
* type of the field represented by this object
*/
public Class getType() {
return type;
}
但对于上述这种泛型的字段, 则通过getType似乎无法得到所要的结果, 我一开始总想着用getType的结果转换, 结果是行不通的. 最后发现必须使用另一个方法才可以:
/**
* Returns a {@code Type} object that represents the declared type for
* the field represented by this {@code Field} object.
*
*
If the {@code Type} is a parameterized type, the
* {@code Type} object returned must accurately reflect the
* actual type parameters used in the source code.
*
*
If the type of the underlying field is a type variable or a
* parameterized type, it is created. Otherwise, it is resolved.
*
* @return a {@code Type} object that represents the declared type for
* the field represented by this {@code Field} object
* @throws GenericSignatureFormatError if the generic field
* signature does not conform to the format specified in
* The Java™ Virtual Machine Specification
* @throws TypeNotPresentException if the generic type
* signature of the underlying field refers to a non-existent
* type declaration
* @throws MalformedParameterizedTypeException if the generic
* signature of the underlying field refers to a parameterized type
* that cannot be instantiated for any reason
* @since 1.5
*/
public Type getGenericType() {
if (getGenericSignature() != null)
return getGenericInfo().getGenericType();
else
return getType();
}
但这个是Type的类型, 它仅仅是一个空的接口:
/**
* Type is the common superinterface for all types in the Java
* programming language. These include raw types, parameterized types,
* array types, type variables and primitive types.
*
* @since 1.5
*/
public interface Type {
}
它是Class类及泛型类型ParameterizedType的基类, 所以实现代码如下:
Type type = field.getGenericType();
if (!(type instanceof ParameterizedType))
{
throw new Exception("Parameterized type should be used");
}
ParameterizedType pt = (ParameterizedType)type;
Type[] actualTypes = pt.getActualTypeArguments();
if (actualTypes.length > 1)
{
throw new Exception("Only One parameter type is support, actuall number is:" + actualTypes.length);
}
if (actualTypes.length == 0)
{
throw new Exception("parameter type should be used");
}
unitClazz = (Class)actualTypes[0];
unitClazz的结果就是等同于Person.class