关于Java的泛型在所声明的对象中如何获取class或者实例的方法的总结

转载 2016年08月31日 15:55:46

前段时间写过JSON字符串解析的代码,大部分工作都是在重复的写相同逻辑的代码,心血来潮打算用泛型解决这个重复的过程,结果可想而知一路上到处遇到问题,不过还好最后还是找到了解决办法。下面总结一下,一是自己备忘一下,二是分享一下。

总得说有两种方式可以解决这个问题,一种看上去技术含量很低,但是效果很好,也很简单,另一种要高一点,而且也很麻烦,在显示开发的时候也要不停的建造子类。

  • 技术含量比较的低的方式:

    泛型类

1 public class JSONUtil<T> {
2     public T analytic2Object(Class<T> tClass, String str)
3             throws InstantiationException, IllegalAccessException {
4         return tClass.newInstance();
5     }
6 }

      数据类

1 public class TestObject {
2     public void printName() {
3         System.out.println("TestObject");
4     }
5 }

    测试类

复制代码
1 public class TestMain {
2     public static void main(String[] args) throws InstantiationException,
3             IllegalAccessException {
4         JSONUtil<TestObject> util = new JSONUtil<TestObject>();
5         TestObject obj = util.analytic2Object(TestObject.class, "");
6         obj.printName();
7     }
8 }
复制代码

看完这个代码后你可能会问,为什么要在方法中传个class进去呢?为什么不通过T这个泛型来获取呢?既然要传class进去干吗还用泛型呢?下面来回答一下几个问题:

为什么要在方法中传个class进去呢,原因很简单,在我们的这个工具类中根本没法根据T这个泛型来获取它的class;无法的获取的原因是:泛型是在编译期获得的,而且有擦除机制。所以在编译前不知道T是啥,编译后又被擦除了;那么这个还有必要使用泛型么?回答是可以不用泛型,因为拿到class后一切问题都解决了,但是有一个问题就是你的方法返回的对象只能是Object,然后在调用的地方进行强制类型转换了。

    不用泛型传递class的代码如下:

1 public class JSONUtil {
2     public Object analytic2Object(Class tClass, String str) throws InstantiationException, IllegalAccessException {
3         return tClass.newInstance();
4     }
5 }

 

  • 通过泛型来获取class的方法:

这时你可能会疑问:你上边不是说不能通过泛型来获取么?这里怎么又可以了?请注意前面我那句话“在我们的这个工具类中根本没法根据T这个泛型来获取它的class”,也就是说我们可以通过另一中方式来实现这个获取class的目的,下面我大体说一下这个获取的方法:

  1. 创建我们的泛型类让它做基类或者抽象类,为什么不用接口呢?因为我们要在这个泛型类上写所有的解析JSON的逻辑代码;
  2. 添加通过泛型拿到class的方法;
  3. 写一个没有泛型的类继承这个泛型类,并将泛型的类型在集成的时候写明确,这样在编译的时候就知道泛型的类型了,第2步的那个代码才能生效,如果不继承直接用这个基类第2步的代码是会出异常的,不信你可以试试;
  4. 在我们的代码中调用泛型类的子类的方法就能正常了。

这个方法最大的弊病是:我们每添加一个要解析出的数据类时都要添加这么一个泛型类的子类,好处是这个子类不需要写任何代码,因为逻辑都在泛型的基类中实现了。

   泛型基类

复制代码
 1 import java.lang.reflect.ParameterizedType;
 2 import java.lang.reflect.Type;
 3 
 4 public abstract class AbsJSONUtil<T> {
 5     public T getT() throws InstantiationException, IllegalAccessException {
 6         Type sType = getClass().getGenericSuperclass();
 7         Type[] generics = ((ParameterizedType) sType).getActualTypeArguments();
 8         Class<T> mTClass = (Class<T>) (generics[0]);
 9         return mTClass.newInstance();
10     }
11 }
复制代码

  泛型子类

1 public class JSONUtilForTestObject extends AbsJSONUtil<TestObject> {
2 
3 }

  测试类

复制代码
1 public class TestMain {
2     public static void main(String[] args) throws InstantiationException,
3             IllegalAccessException {
4         JSONUtilForTestObject go = new JSONUtilForTestObject();
5         TestObject obj = go.getT();
6         obj.printName();
7     }
8 }
复制代码

相关文章推荐

java泛型T.class的获取

   很早之前写过利用泛型和反射机制抽象DAO ,对其中获取子类泛型的class一直不是很理解。关键的地方是HibernateBaseDao的构造方法中的Type genType = getClass...
  • ykdsg
  • ykdsg
  • 2010年04月11日 13:43
  • 58878

Java通过Class的对象来获取泛型的class示例

Java通过Class的对象来获取泛型的class示例
  • rzg813
  • rzg813
  • 2014年10月12日 19:23
  • 2902

java泛型得到T.class

import java.lang.reflect.ParameterizedType; public class Test { public Class getTClass() { retur...

Java通过Class的对象来获取泛型的class示例

在使用spring的JdbcTemplate实现DAO的时候,经常会用到一个类ParameterizedBeanPropertyRowMapper。它的静态方法newInstance()接受一个Cla...

java泛型T.class的获取

很早之前写过利用泛型和反射机制抽象DAO ,对其中获取子类泛型的class一直不是很理解。关键的地方是HibernateBaseDao的构造方法中的 [java] view ...

封装篇——获取泛型<T>的Class<T> clazz

在我们搭建框架中往往会用到泛型,我们知道泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,代码的重用率高, 然而有时候``的入参并不能直接强制转换成泛型的类型,这就有所限制.....

java创建一个对象获取泛型的class

孔浩老师视频笔记。  private Class clz;          @SuppressWarnings("unchecked")   public Class getClz(...

Java 得到泛型中得到T.class

原文地址http://blog.csdn.net/gengv/article/details/5178055 在使用spring的JdbcTemplate实现DAO的时候,经常会...

获取泛型类型T的实际类的Class对象

import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; //abstract public  c...

JAVA泛型应用-获取容器运行时的泛型Class对象

JAVA泛型应用,获取容器运行时的泛型Class对象。
  • ai_zxc
  • ai_zxc
  • 2016年02月01日 10:24
  • 790
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于Java的泛型在所声明的对象中如何获取class或者实例的方法的总结
举报原因:
原因补充:

(最多只允许输入30个字)