【问题标题】:Why it is not possible to create a generic fill method in Java?为什么不能在 Java 中创建通用填充方法?
【发布时间】:2009-05-04 16:37:22
【问题描述】:

我有以下课程:

abstract class DTO{ }

class SubscriptionDTO extends DTO { }

以及以下通用方法:

protected void fillList(ResultSet rs, ArrayList<? extends DTO> l)
        throws BusinessLayerException {
    SubscriptionDTO bs;
    try {
        while (rs.next()){
            //initialize bs object...
            l.add(bs); //compiler error here
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }

}

我似乎无法理解为什么您不能创建一个通用方法来填充 DTO 子类型。我做错了什么还是设计使然?如果是这样,是否有任何解决方法?提前致谢。

【问题讨论】:

  • 要回答,我需要看看你是如何初始化bs的,至少是类型声明。
  • 我认为您无法按计划编写泛型方法,因为您需要知道 bs 对象的确切类型才能创建它。例如,new SubscriptionDTO() 或 new DeliveryDTO()。
  • @javashlook -你是对的。 mmyers 的解释足以让我意识到这一点。看来我会继续使用原始解决方案来解决这类问题。

标签: java generics


【解决方案1】:

您应该使用&lt;? super DTO&gt;(或&lt;? super SubscriptionDTO&gt;,正如Tom Hawtin - tackline 指出的那样)作为ArrayList 的通用参数。

来自Effective Java 的第 28 项(sample chapter [pdf] 的第 28 页):

这里有一个助记符,可帮助您记住要使用的通配符类型:

PECS 代表生产者扩展,消费者超级。

换句话说,如果一个参数化类型代表一个T生产者,使用&lt;? extends T&gt;; 如果它代表T 消费者,请使用&lt;? super T&gt;

在这种情况下,l 是一个消费者(您将对象传递给它),因此 &lt;? super T&gt; 类型是合适的。

【讨论】:

  • .
【解决方案2】:

想象以下情况,Foo extends BarZoo extends Bar

List<Foo> fooList = new ArrayList<Foo>();
fooList.addAll(aBunchOfFoos());
aMethodForBarLists(fooList);

那么我们就有了方法本身:

void aMethodForBarLists (List<? extends Bar> barList) {
   barList.add(new Zoo());
}

这里发生的情况是,即使 Zoo 确实扩展了 Bar,您仍试图在 List&lt;Foo&gt; 中添加 Zoo,它是明确为 Foos 制作的,并且仅适用于 Foos。

就是为什么 Java 规范不允许将东西添加到 &lt;? extends Something&gt; 集合中 - 虽然语法 似乎 正确,但不能确定实际的对象将允许将内容添加到集合中。

【讨论】:

    【解决方案3】:

    这应该可行,而且更简单:

    protected void fillList( ResultSet rs, List<DTO> l ) throws BusinessLayerException 
    {
       SubscriptionDTO bs;
       try 
       {
          while   ( rs.next() )
          {
             //initialize bs object...
             l.add( bs );
          }
        }
        catch ( SQLException e ) 
        {
           e.printStackTrace();
        }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-05
      • 2015-02-05
      • 2014-07-16
      • 2021-05-12
      • 1970-01-01
      • 2018-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多