有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java泛型类型使用DbUtils BeanListHandler在可重用JavaFX数据检索服务上摸索

我正在尝试创建一个通用的JavaFX Service,它将使用DbUtils'{}将ObservableList交回应用程序GUI线程。其目的是重用它,将许多表加载到不同bean类的许多不同列表中

我遇到的问题是处理call()方法中的泛型

ICINGBean是一个抽象类,我正在处理的所有bean都继承自extend

public class StaticDataFetcher extends Service<ObservableList<? extends ICINGBean>> {
    private Class<? extends ICINGBean> beanClass;

    @Override
    protected Task createTask() {
        DataGetter dget = new DataGetter();
        dget.setBeanClass(beanClass);
        return dget;
    }

    public Class<? extends ICINGBean> getBeanClass() { return beanClass; }

    public void setBeanClass(Class<? extends ICINGBean> beanClass) { this.beanClass = beanClass; }
}


class DataGetter extends Task<ObservableList<? extends ICINGBean>> {
    private Class<? extends ICINGBean> beanClass;

    @Override
    protected ObservableList<? extends ICINGBean> call() {
        ObservableList<? extends ICINGBean> staticList;
        staticList = FXCollections.observableArrayList();   
        ResultSetHandler<List<? extends ICINGBean>> handler;
        handler = new BeanListHandler<? extends ICINGBean>(beanClass);
        try {
            List<? extends ICINGBean> resultList;
            resultList = EntryPoint.getQRunner().query("SELECT * FROM ?", handler, beanClass.getSimpleName());
            staticList = FXCollections.observableList(resultList);
        } catch (SQLException ex) {
                Logger.getLogger(DataGetter.class.getName()).log(Level.SEVERE, null, ex);
        }
        return staticList;
    }

    public Class<? extends ICINGBean> getBeanClass() { return beanClass; }

    public void setBeanClass(Class<? extends ICINGBean> beanClass) { this.beanClass = beanClass; }
}

我得到的编译时错误是:

.../ICING/src/com/cccg/icing/StaticDataFetcher.java:55: error: unexpected type
            handler = new BeanListHandler<? extends ICINGBean>(beanClass);
                                         ^
  required: class or interface without bounds
  found:    ? extends ICINGBean

我很确定我只是把仿制药处理得一团糟,但我不确定如何处理。我遵循了DbUtils示例页面上的listed example使用BeanListHandler,在我认为适合使用泛型类型的地方进行替换,但我对错误一无所知

非常感谢您的帮助,谢谢

解决了

在下面保罗·贝洛拉的帮助下,我解决了这个问题。我为类声明了一个类型参数,并将其与菱形运算符一起使用

public class StaticDataFetcher<T extends ICINGBean> extends Task<ObservableList<? extends ICINGBean>> {
    private Class<T> beanClass;
    //...

    public StaticDataFetcher(Class<T> beanClass) {
        super();
        this.beanClass = beanClass;
    }

    protected ObservableList<? extends ICINGBean> call() {
        //...
        ResultSetHandler<List<T>> handler;
        handler = new BeanListHandler<>(beanClass);
        //...
    }
}

谢谢大家的帮助,我希望这能帮助别人


共 (2) 个答案

  1. # 1 楼答案

    不允许使用通配符类型参数实例化泛型类型。请参见我在this answer中对原因的解释

    一个简单的解决方案是使用diamond operator(Java 7及更高版本):

    handler = new BeanListHandler<>(beanClass);
    

    如果不可用,则需要使用通用帮助器方法:

    <T extends ICINGBean> BeanListHandler<T> makeContainer(Class<T> beanClass) {
        return new BeanListHandler<T>(beanClass);
    }
    
    ...
    
    handler = makeContainer(beanClass);
    
  2. # 2 楼答案

    我也努力让它在Yank正常工作。以下是我在Java 6中的工作原理:

    public static <T> List<T> queryObjectListSQL(String poolName, String sql, Class<T> type, Object[] params) {
    
        List<T> returnList = null;
    
        Connection con = null;
    
        try {
          con = DB_CONNECTION_MANAGER.getConnection(poolName);
    
          if (con == null) {
            throw new ConnectionException(poolName);
          }
    
          con.setAutoCommit(false);
    
          BeanListHandler<T> resultSetHandler = new BeanListHandler<T>(type);
    
          returnList = new QueryRunner().query(con, sql, resultSetHandler, params);
    
          con.commit();
    
        } catch (Exception e) {
          logger.error(QUERY_EXCEPTION_MESSAGE, e);
          try {
            con.rollback();
          } catch (SQLException e2) {
            logger.error(ROLLBACK_EXCEPTION_MESSAGE, e2);
          }
        } finally {
          DB_CONNECTION_MANAGER.freeConnection(poolName, con);
        }
    
        return returnList;
      }
    

    完整的源代码是here。上面的代码显然不同于您的确切示例,但您可以看到泛型是如何工作的。这样做的好处是,调用该方法时根本不需要强制转换

    我希望这能有所帮助