当你意识到你不懂Java时那个尴尬的时刻...
获得类A,B和C.它们都扩展了类X,它定义了UUID id,getId()和setId()
(旁注 - X及其与A,B,C和D的关系是固定的,不可更改)
编写相同的方法后
findA(UUID id, List<A> as)
findB(UUID id, List<B> bs)
findC(UUID id, List<C> cs)
,所有这些只返回一个匹配id的A(B,C),我觉得我需要做一些重构。
天真,我想 - 哦,我知道,我会让A,B和C实现一个接口,用Identifiable
称它为UUID getId()
,使用, mutatus mutandis ,来自findA
的代码,并将其称为一天 - findIdentifiable(UUID id, List<Identifiable> list)
将完成这些操作。
嗯,不;无法在List<A>
(或<B>
或<C>
)上调用findIdentifiable。哎哟!有点尴尬,我没有看到它的到来 - 更糟糕的是,我甚至不明白它为什么不编译。
这是第一个问题。第二个问题是 - 进行这种重构的最佳方法是什么?因为路上有更多的课程,我不想写另一个相同的方法...
我在想“泛型”,但显然,尽管在简单的情况下使用泛型,我不知道如何处理这种情况。
答案 0 :(得分:4)
你能做的是:
Identifiable findIdentifiable(UUID id, List<? extends Identifiable> list) {
for (Identifiable ident : list) {
if (ident.getId().equals(id))
return ident;
}
return null;
}
因为你不能将通用参数子类化。
但是,由于您已经X
扩展了A
,B
和C
,为什么不用X
代替是Identifiable
?
X findIdentifiable(UUID id, List<? extends X> list) {
for (X ident : list) {
if (ident.getId().equals(id))
return ident;
}
return null;
}
答案 1 :(得分:1)
如果希望方法返回与列表类型相同的类型,则需要键入方法:
public <T extends Identifiable> T find(UUID id, List<T> items) {
for (T item : items) {
if (item.getId().equals(id))
return item;
}
return null;
}
使用此签名,以下调用将在没有警告的情况下编译:
List<A> aList;
A found = find(id, aList);