【问题标题】:generics in constructors in Java?Java构造函数中的泛型?
【发布时间】:2014-02-13 00:05:29
【问题描述】:

考虑这个假设的课程(我在一个在线视频中找到):

public class Contrived<T extends Number> extends ArrayList<T> {
      List <? extends T> values;
      ......
    }

这里Contrived 可以接受的类型变量是NumberNumber 的某个子类型。但是类本身继承自ArrayList,所以无论类得到什么类型,都将决定ArrayList的类型。

现在有一个名为values 的字段,即List&lt;? extends T values&gt;。那么这意味着什么? list 是否可以容纳扩展 T 的任何内容(进而扩展 Number)。

通过PECS (producer extends, consumer super) 规则,我可以只使用这个List 读取元素而不添加到list

如果我需要传递list of doubles or some type Tconstructor 会是什么样子?

【问题讨论】:

  • 我不认为我完全理解 Contrived 类背后的想法。它应该做什么?它扩展了ArrayList,并有一个列表values 作为参考变量。因此该类基本上包含两个列表,该类的目的是什么?一个有用的构造函数取决于它(例如“构造函数应该做什么?”)。你能链接到源吗?
  • @dst:这是一个假设的类。它这样做并不重要。但我想知道它的构造函数会是什么样子以及给定的list 字段可以执行哪些操作?
  • public Contrived(List&lt;T&gt; list) ?
  • @HighCore @user1988876 或 public Contrived(List&lt;? extends T&gt; list)?还是你想要一个方法体?
  • @HighCore:构造函数不应该是public Contrived(List&lt;? extends T&gt; list)

标签: java generics wildcard bounded-wildcard


【解决方案1】:

您可以有一个采用List&lt;T&gt;List&lt;? extends T&gt; 的构造函数。继续设计类:

class B extends Number{
   public double doubleValue() { return 0; }
   public float floatValue() { return 0; }
   public long longValue() { return 0; }
   public int intValue() { return 0; }
}
class C extends B{}

我向Contrived 类添加了一个人为的合法构造函数,采用List&lt;? extends T&gt;

public Contrived(List<? extends T> values)
{
   this.values = values;
}

这允许我编写一个main 方法,如下所示:

public static void main(String[] args)
{
   List<C> bList = Arrays.asList(new C(), new C(), new C());
   Contrived<B> ci = new Contrived<B>(bList);
}

我可以将List&lt;C&gt; 传递给Contrived&lt;B&gt; 的构造函数。

Contrived 合法的人为构造函数的另一种设计可能是采用List&lt;T&gt;

public Contrived(List<T> values)
{
   this.values = values;
}

这样的构造函数不允许将List&lt;C&gt; 用于Contrived&lt;B&gt;,因为现在类型必须匹配,如以下两个Contrived 示例:

public static void main(String[] args)
{
   List<C> cList = Arrays.asList(new C(), new C(), new C());
   Contrived<C> ci = new Contrived<C>(cList);  // must match now
}

public static void main(String[] args)
{
   List<B> bList = Arrays.asList(new B(), new B(), new B());
   Contrived<B> ci = new Contrived<B>(bList);  // must match now
}

【讨论】:

  • 只要我们说话做作,你也可以将this分配给values
  • @Radiodef 确认,您设计的示例this.values = this; 在我设计的Contrived 构造函数中是合法的。
  • 在重载的情况下可以同时拥有两个构造函数;但我想在这种情况下这没有意义;因为第一个是后者受限版本的宽松版本..?
  • @user1988876 实际上你不能同时拥有两者,因为它们具有相同的擦除。它们只是两个不同的例子。
猜你喜欢
  • 2013-10-13
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多