4

此代码在 Java 6 下编译良好,但切换到 Java 7 时会导致编译时错误“对 Foo 的引用不明确,com.company.Foo 中的构造函数 <I,C>Foo(C) 和构造函数 <I>Foo (I) 在 com.company.Foo 匹配"

/**
 * Constructor A - acts on a Collection of Iterables
 */
public <I extends Iterable<T>, C extends Collection<I>> Foo(C intervalSeries) {
    initialize(intervalSeries);
}

/**
 * Constructor B - convenience constructor for callers who only have 1 Iterable
 */
public <I extends Iterable<T>> Foo(I intervals) {
    List<I> intervalSeries = newArrayList(1);
    intervalSeries.add(intervals);
    initialize(intervalSeries);
}

我明白为什么(集合是可迭代的)。我计划编写一个 Builder 辅助类,而不是通过提供一个不同名称的构建器方法来解决这个问题,但在此之前我想我会问:没有魔法通配符或超级咒语会让我摆脱这个,对吧?

4

2 回答 2

8

你过度使用泛型。

您可以简单地采用Collection<I>, 并且它的任何子类都将隐式转换为该接口。

事实上,你根本不需要类型参数;你可以写

public Foo(Collection<? extends Iterable<T>> intervalSeries)
public Foo(Iterable<T> intervals)

您可能还想更改T? extends T.

于 2013-10-16T17:13:36.707 回答
0

虽然@SLaks 有最好的答案,但只是想补充一点,使用工厂方法是构建器的一种可能替代方案,因为您可以命名它们。例如(我可能有泛型错误)

public static <I extends Iterable<T>> Foo makeFooFromIterable(I intervals) { ... }

public static <ignore the gererics part about C> Foo makeFooFromCollection(C c) { ... }
于 2013-10-16T17:20:33.787 回答