Java反射操作泛型接口

通过反射获取到抽象类或者接口中泛型信息的操作也是很常见的。实际上开发中,解析后台数据的Json数据,生成对应的泛型实体类,会用到反射获取泛型信息的操作。

实战案例


大致思路:

  • getGenericInterfaces()获取到泛型接口的Type数组。

  • getActualTypeArguments()获取到泛型接口的实际类型。

1. 定义一个泛型的接口

package com.xingen.classdemo.genericity;

/**
 * Created by ${新根} on 2018/2/16 0016.
 * 博客:http://blog.csdn.net/hexingen
 *
 * 参考:https://www.cnblogs.com/whitewolf/p/4355541.html
 */
public interface GenericityInterface {

    T doThing(K k);

}

2. 定义一个实现类,用于获取指定具体的类型

package com.xingen.classdemo.genericity;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * Created by ${新根} on 2018/2/16 0016.
 * 博客:http://blog.csdn.net/hexingen
 * 

* 反射获取泛型信息 */ public class GenericityInterfaceImp implements GenericityInterface { //泛型中的两个类型 private Class kClass,tClass; public GenericityInterfaceImp() { getGenericityMessage(GenericityInterfaceImp.class); } @Override public Bean doThing(String s) { return new Bean(s); } public void getGenericityMessage(Class mClass) { try { //获取泛型接口 Type[] intefaceTypeArray = mClass.getGenericInterfaces(); if (intefaceTypeArray == null && intefaceTypeArray.length == 0) { return; } //获取实现的第一个接口类型 Type type = intefaceTypeArray[0]; if (!(type instanceof ParameterizedType)) { //这是Object类型 return; } //获取到实际的泛型中参数类型 Type[] parameterizedType = ((ParameterizedType) type).getActualTypeArguments(); kClass=TypeUtils.getClass(parameterizedType[0]); tClass=TypeUtils.getClass(parameterizedType[1]); }catch (Exception e){ e.printStackTrace(); } } public Class getkClass() { return kClass; } public Class gettClass() { return tClass; } public static GenericityInterfaceImp newInstance(){ return new GenericityInterfaceImp(); } }

3. 定义一个工具类:用于Type和Class之间的转换。

package com.xingen.classdemo.genericity;

import java.lang.reflect.Type;

/**
 * Created by ${新根} on 2018/2/16 0016.
 * 博客:http://blog.csdn.net/hexingen
 *
 * 通过Type获取对象class
 */
public class TypeUtils {
    private static final String TYPE_NAME_PREFIX = "class ";

    public static String getClassName(Type type) {
        if (type==null) {
            return "";
        }
        String className = type.toString();
        if (className.startsWith(TYPE_NAME_PREFIX)) {
            className = className.substring(TYPE_NAME_PREFIX.length());
        }
        return className;
    }

    public static Class getClass(Type type)
            throws ClassNotFoundException {
        String className = getClassName(type);
        if (className==null || className.isEmpty()) {
            return null;
        }
        return Class.forName(className);
    }
}

4. 定义一个实体类:用于指定泛型中实际类型

public class Bean {
    private String work;

    public Bean() {
    }

    public Bean(String work) {
        this.work = work;
    }

    public String getWork() {
        return work;
    }

    public void setWork(String work) {
        this.work = work;
    }
}

5. 程序入口main(),运行:

public class Client {

    public static void main(String[] args) {
        useGenericity();
    }

    /**
     * 反射泛型信息
     */
    public static  void useGenericity(){
        GenericityInterfaceImp imp=GenericityInterfaceImp.newInstance();
        System.out.println("反射接口中泛型参数: K是 "+imp.getkClass().getName()+" T 是:"+imp.gettClass().getName());
    }
}

6. 运行结果如下

反射接口中泛型参数: K是 java.lang.String T 是:com.xingen.classdemo.genericity.Bean

本案例的项目代码: https://github.com/13767004362/JavaDemo/tree/master/ClassDemo

你可能感兴趣的:(编程基础(Java,Kotlin,SQL),Java,SE知识点)