2

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

我遇到的问题是call()处理Task.

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 示例页面上列出的示例来使用 BeanListHandler,将我认为适合使用泛型类型的地方替换为它,但我对错误一无所知。

非常感谢任何帮助,谢谢!

解决了!

在下面 Paul Bellora 的有用建议下,我能够解决这个问题。我为该类声明了一个类型参数,并将其与菱形运算符一起使用。

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);
        //...
    }
}

感谢大家的帮助,我希望这对其他人有帮助!

4

2 回答 2

1

不允许使用通配符类型参数实例化泛型类型。请参阅我在此答案中对原因的解释。

一个简单的解决方案是使用菱形运算符(Java 7 及更高版本):

handler = new BeanListHandler<>(beanClass);

如果这不可用,则需要使用通用辅助方法:

<T extends ICINGBean> BeanListHandler<T> makeContainer(Class<T> beanClass) {
    return new BeanListHandler<T>(beanClass);
}

...

handler = makeContainer(beanClass);
于 2013-04-03T03:16:31.673 回答
0

我也在努力让它在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;
  }

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

我希望这会有所帮助。

于 2013-04-03T16:58:10.357 回答