【问题标题】:Creating a virtual template method in Java在 Java 中创建虚拟模板方法
【发布时间】:2012-09-18 18:13:13
【问题描述】:

我试图创造的情况如下:

我有一个包含静态模板方法的基类,该方法接收由数据库中的查询填充的ResultSet,并返回一个包含正确结果的列表。

我有一些派生自上面引用的类,它们代表数据库中的每个表,并且它们都有一个构造函数,它接收ResultSet 并构建对象。

我写的代码是:

public class TableBase 
{
    public static <T extends TableBase> List<T> getResults(ResultSet p_Rs) throws SQLException, InstantiationException, IllegalAccessException
    {
        List<T> v_Table = new ArrayList<T>();
        T v_TB = null;
        while(p_Rs.next())
            v_Table.add(new T(p_Rs));
        return v_Table;
    }
}

我得到的错误是:Cannot instantiate the type T

我很清楚,编译器有必要“知道”所有子类都将实现接收ResultSet 变量的构造函数,但我无法创建“抽象构造函数”。

有人知道如何解决这个问题吗?

提前谢谢大家。

【问题讨论】:

  • 你必须向函数传递一些知道T的对象。也许某种工厂对象

标签: java templates virtual resultset


【解决方案1】:

你不能那样做。您必须告诉运行时确切的类型。

也许你可以这样做:

  1. TableBase 必须有一个默认构造函数。
  2. TableBase 必须有一个 setResultSet 方法。

    public class TableBase {
      public static <T extends TableBase> List<T> getResults(ResultSet p_Rs, Class<T> clazz)
            throws SQLException, InstantiationException, IllegalAccessException {
        List<T> v_Table = new ArrayList<T>();
        T v_TB = clazz.newInstance();
        while (p_Rs.next())
            v_TB.setResultSet(p_Rs);
        v_Table.add(v_TB);
        return v_Table;
      }
    }
    

【讨论】:

    【解决方案2】:

    您不能实例化泛型类型。

    你可以使用任一工厂

     public static <T extends TableBase> List<T> getResults
     (ResultSet p_Rs, Factory<T> factory)
    
    //Create instance using factory 
    

    或作为类型的类。

    public static <T extends TableBase> List<T> getResults
    (ResultSet p_Rs, Class<T> type)
    //type.newInstance()
    

    【讨论】:

      【解决方案3】:

      您可以使用反射,例如:

      while(p_Rs.next())
              v_Table.add(newInstance(T, p_Rs));
      
      
      public <T extends TableBase> T newInstance(T t, ResultSet p_Rs){
             try {
                  Constructor constructor = t.getClass().getDeclaredConstructor(ResultSet.class); 
                  return (T)constructor.newInstance(p_Rs);
      
              } catch (Exception e) {
                  throw new RuntimeException();
              } 
      
      }
      

      【讨论】:

        猜你喜欢
        • 2016-09-28
        • 2011-12-19
        • 2014-10-25
        • 2018-09-06
        • 2011-11-28
        • 2018-11-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多