反射专题5

来源:互联网 发布:在线注音软件 编辑:程序博客网 时间:2024/06/05 10:19

-1-泛型和Class类

从JDK5以后,Java的Class类增加了泛型功能,从而允许使用泛型来限制Class类。如果Class对应的类暂时未知,则使用Class<?>,通过在反射中使用泛型,可以避免使用泛型生成的对象需要强制类型转换。

public class CrazyitObjectTest{    public static Object getInstance(String clsName)    {        try        {            Class cls = Class.forName(clsName);            return cls.newInstance();        }        catch (Exception e)        {            e.printStackTrace();            return null;        }    }}

上面代码将返回一个新的对象,但由于这个对象的类型是Object,因此需要强制类型转换:

Date d = (Date) CrazyitObjectTest.getInstance(“java.util.Date”);

使用泛型之后的效果,不需要类型转换

public class CrazyitObjectTest{    public static <T> T getInstance(Class<T> cls)    {        try        {            return cls.newInstance();        }        catch (Exception e)        {            e.printStackTrace();            return null;        }    }}Date d = CrazyitObjectTest.getInstance(Date.class);Intent intent = CrazyitObjectTest.getInstance(Intent.class);

-2-使用反射来获取泛型消息

获取了成员变量的Field对象后,就可以很容易地获取该成员变量的数据类型,如下:

//获取成员变量f的类型Class<?> a = f.getType();

但这种方式只对普通类型的成员变量有效。如果该成员变量的类型是有泛型类型的类型,如果Map<String , Integer>类型,则不能准确地得到该成员变量的泛型参数。

通过下面方式来获取该成员变量的泛型类型:

//获取成员变量f的泛型类型
Type gType = f.getGenericType();

然后将Type对象强制类型转换为ParameterizedType对象,ParameterizedType代表被参数化的类型,也就是增加了泛型限制的类型。ParameterizedType类型提供了如下两个方法:

(1)getRawType():返回没有泛型消息的原始类型;

(2)getActualTypeArguments():返回泛型参数的类型。

例子:

public class GenericTest{    private Map<String , Integer> score;    public static void showGeneric() throws Exception    {        Class<GenericTest> clazz = GenericTest.class;        Field f = clazz.getDeclaredField("score");        //直接使用getType()取出类型只对普通类型的成员变量有效        Class<?> a = f.getType();        //下面将看到仅输出java.util.Map        Log.d("GenericTest" , "score的类型是:" + a);        //获取成员变量f的泛型类型        Type gType = f.getGenericType();        //如果gType类型是ParameterizedType对象        if (gType instanceof ParameterizedType)        {            //强制类型转换            ParameterizedType pType = (ParameterizedType) gType;            //获取原始类型            Type rType = pType.getRawType();            Log.d("GenericTest" , "原始类型是:" + rType);            Type[] tArgs = pType.getActualTypeArguments();            Log.d("GenericTest" , "泛型消息是:");            for (int i = 0 ; i < tArgs.length ; i++)            {                Log.d("GenericTest" , "第" + i + "泛型类型是:" + tArgs[i]);            }        }    }}

输出:
score的类型是:interface java.util.Map
原始类型是:interface java.util.Map
泛型消息是:
第0泛型类型是:class java.lang.String
第1泛型类型是:class java.lang.Integer

例子2(将泛型类型转换为Gson解析时需要的Type类型)

public abstract class BaseCallBack<T>{    public Type mType;    static Type getSuperclassTypeParameter(Class<?> subClass)    {        Type superclass = subClass.getGenericSuperclass();        if (superclass instanceof Class)        {            throw new RuntimeException("Missing type parameter.");        }        ParameterizedType parameterized = (ParameterizedType) superclass;        return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);    }    public BaseCallBack()    {        mType = getSuperclassTypeParameter(getClass());    }}

Type是java.lang.reflect包下的一个接口,该接口代表所有类型的公共高级接口,Class是Type接口的实现类。

0 0
原创粉丝点击