Java泛型的实例化总结

前言: 当我们在做项目的时候 ,搭建框架的时候,会经常用到泛型类来封装一些通用类或工具类。在封装泛型类的过程中,为了提升开发效率及代码简洁,会经常运用泛型内部进行实例化,用以减少代码量或重复操作。

创建泛型类

public class GenericityTest<T,D,E> {
   T t;
   D d;
   E e;
}



1 泛型的实例化
(1)getClass().getGenericSuperclass()).getActualTypeArguments()[0].newInstance();

   

public void init(){      try {
         Type[] typeArguments = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments();
         for(Type type : typeArguments){
            System.out.println("type:"+type);//打印映射的实际类
         }
         Class<T> tClass = (Class<T>) typeArguments[0];
         Class<D> dClass = (Class<D>) typeArguments[1];
         Class<E> cClass = (Class<E>) typeArguments[2];
         this.t = tClass.newInstance();
         this.d = dClass.newInstance();
         this.e = cClass.newInstance();
      } catch ( Exception e) {
         e.printStackTrace();
      }
   }



(2) getConstructor().newInstance()

public void init(){

      try {
         Type[] typeArguments = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments();
         for(Type type : typeArguments){
            System.out.println("type:"+type);
         }
         T e = (T) ((Class)typeArguments[0]).getConstructor().newInstance();
         D e = (D) ((Class)typeArguments[1]).getConstructor().newInstance();
         E e = (E) ((Class)typeArguments[2]).getConstructor().newInstance();
      } catch ( Exception e) {
         e.printStackTrace();
      }
   }



(3) Class.forName(className).newInstance() 

  public void init(){

      try {
         Type[] typeArguments = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments();
         for(Type type : typeArguments){
            System.out.println("type:"+type);//打印映射的实际类
         }
         T t = (T) Class.forName(typeArguments[0].getTypeName()).newInstance();
         D d = (D) Class.forName(typeArguments[1].getTypeName()).newInstance();
         E e = (E) Class.forName(typeArguments[2].getTypeName()).newInstance();
      } catch ( Exception e) {
         e.printStackTrace();
      }
   }

2 注意的是
泛型的实例化不能用于抽象类、接口、数组类、基本类型或void,以及泛型类;
泛型类的泛型类 是什么意思?
例如: HashMap<String,String> 这些方法都不能创建出该对象,如果只是HashMap可以,HashMap<String,String>就不行

===================================================================

实例化具有无参数构造函数的泛型对象

//newInstance() method need constructor without parameter
//Class<T> come form Class.class
public <T> T getNewObject(Class<T> cls) {
    T t=null;
    try {
        t = cls.newInstance();
    } catch (InstantiationException|IllegalAccessException e) {
        e.printStackTrace();
    }
    return t;
}



调用

String i =getNewObject(String.class);



这种方法需要泛型类具有一个无参数构造函数实例化没有无参数构造函数的泛型对象

//newInstance() method need constructor with parameter
public <T> T getNewObject(Constructor<T> cls, double d) {
    T t = null;
    try {
        t = cls.newInstance(d);
    } catch (InstantiationException | IllegalAccessException
             | IllegalArgumentException | InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return t;
}


调用

con = Float.class.getConstructor(double.class);
Float k =getNewObject(con,10.0);


这种方法先确定使用泛型类的哪一个构造函数,再通过该构造函数newInstance实例出来。

通用的实例泛型对象(无需区别是否有无参数构造函数)通过反射动态创建泛型实例

public class BasePresenter<V extends BaseView,M extends BaseModel>{

    private M mModel;

    public void attach(){

          //1、返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type
        Type genType = getClass().getGenericSuperclass();
        //2、泛型参数
        Type[] types = ((ParameterizedType) genType).getActualTypeArguments();
        //3、因为BasePresenter 有两个泛型 数组有两个
        try {
            //
            mModel= (M) ((Class)types[1]).newInstance();
            //这里需要强转得到的是实体类类路径
//            如果types[1].getClass().newInstance();并不行,得到的是泛型类型
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public M getModel(){

        return mModel;
    }

}


getSuperclass和 getGenericSuperclass的区别
getSuperclass返回直接继承的父类不包括泛型参数
getGenericSuperclass返回直接继承的父类包含泛型参数
getInterfaces 和 getGenericInterface 的区别
getInterfaces 返回直接实现的接口(不显示泛型参数)
getGenericInterface 返回直接实现的接口(显示泛型参数)
封装成工具类
 

public class ReflectionUtil {

    /**
     * 通过type获取className
     */

    public static String getClassName(Type type){
        if(type==null){

            return "";
        }
        String className = type.toString();

        if (className.startsWith("class")){
            className=className.substring("class".length());
        }
        return className;
    }

    /**
     * 获取子类在父类传入的泛型Class类型
     * 获取泛型对象的泛型化参数
     * @param o
     * @return
     */
    public static Type getParameterizedTypes(Object o){
        Type superclass = o.getClass().getGenericSuperclass();
        if(!ParameterizedType.class.isAssignableFrom(superclass.getClass())) {
            return null;
        }
        Type[] types = ((ParameterizedType) superclass).getActualTypeArguments();
        return types[0];
    }

    /**
     * 获取实现类的泛型参数
     * @param o
     * @return
     */

    public static Type getInterfaceTypes(Object o){
        Type[] genericInterfaces = o.getClass().getGenericInterfaces();

        return genericInterfaces[0];
    }

    /**
     *检查对象是否存在默认构造函数
     */

    public static boolean hasDefaultConstructor(Class<?> clazz) throws SecurityException {
        Class<?>[] empty = {};
        try {
            clazz.getConstructor(empty);
        } catch (NoSuchMethodException e) {
            return false;
        }
        return true;
    }
    /**
     * 通过Type创建对象
     */
    public static Object newInstance(Type type)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class<?> clazz = getClass(type);
        if (clazz==null) {
            return null;
        }
        return clazz.newInstance();
    }


    /**
     * 通过Type获取对象class
     * @param type
     * @return
     * @throws ClassNotFoundException
     */

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


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值