我遇到一个简单的Java代码问题。
我无法确定它是否解决了原来的目的;
写它的那个人(但是无法到达)只是告诉了我
“实现IA
的对象应该是List
的容器(IB
) - 就像对象一样”。乍一看我认为它错了,
因为强约束(T extends IB<T>
)似乎不合逻辑,
但IDE编译器未显示任何相关的错误/警告。
如果此类代码有意义, 有人可以提供这种接口的实际使用示例。
提前致谢。
import java.util.List;
public interface IA<T extends IB<T>> {
public List<T> getList();
}
public interface IB<T> {
public T getValue();
}
更新1 :使用具体样本类添加测试
class Bar implements IA<Foo>{
List<Foo> list;
@Override
public List<Foo> getList() {
return list;
}
Bar(List<Foo> foos) {
this.list = foos;
}
}
class Foo implements IB<Foo> {
public Float data;
@Override
public Foo getValue() {
return foo;
}
Foo(Float data){
this.data = data;
}
public Float getV() {
return data;
}
}
public class DataTest {
@Test
public void myTest() {
Foo f = new Foo(10F);
List<Foo> fs = new ArrayList<>();
fs.add(f);
Bar bar = new Bar(fs);
List<Foo> foos = bar.getList();
System.out.println(foos.get(0).getV());
}
}
这是使用IA和IB的正确方法吗?
答案 0 :(得分:0)
由于T
仅用于协变位置,因此可以安全使用,因此对IA
的评论可能是正确的。如果IA
在其某个参数中有一个接受T
(如int compare(T a, T b)
)的方法,则会导致出现问题,因为它处于逆变位置。
答案 1 :(得分:0)
这种约束在某些情况下是有道理的。例如,如果要创建排序列表类,可以执行类似
的操作class SortedList<T extends Comparable<? super T>>
您需要将元素类型与自身进行比较,这是您对其进行排序所必需的。 (请注意,Comparable
本身在其类型参数上没有绑定,就像这里一样。)
上述内容中的super
是因为Comparable
是T
的使用者,因此根据PECS,您应该使用super
通配符{{1} }}。在您的情况下,由于Comparable
是与IB
相关的制作人,因此如果您想使其最为通用,则可以将其设为T
。
对于使用此约束的实际用例,我提出的是使用约束的类:
public interface IA<T extends IB<? extends T>>
如果您有一个实现类,它本身是通用的(绑定了相同的class Bar<T extends IB<T>> implements IA<T> {
T start;
@Override
public List<T> getList() {
List<T> result = new ArrayList<T>();
for (T x = start; x; x = x.getValue()) {
result.add(x);
}
return result;
}
Bar(T start) {
this.start = start;
}
}
),它需要一个<T extends IB<T>>
并生成更多T
s,直到达到T
},并返回这些列表。
虽然这仍然不要求接口null
具有约束,所以我想它仍然没有提供一个例子,其中IA
参数的绑定是必要的。