在返回集合的接口中使用Java泛型。最佳实践?陷阱?
我今天遇到了一些我觉得有问题的代码。下面是一个简化的示例(不现实) 然后有这样一个实现者:在返回集合的接口中使用Java泛型。最佳实践?陷阱?,java,generics,oop,collections,interface,Java,Generics,Oop,Collections,Interface,我今天遇到了一些我觉得有问题的代码。下面是一个简化的示例(不现实) 然后有这样一个实现者: public GroceryList implements IListable { private ArrayList<GroceryItem> groceries; public GroceryList() { this.groceries = new ArrayList<GroceryItem>(); } public Arr
public GroceryList implements IListable {
private ArrayList<GroceryItem> groceries;
public GroceryList() {
this.groceries = new ArrayList<GroceryItem>();
}
public ArrayList<GroceryItem> getFirstNThings(int n) {
ArrayList<GroceryItem> firstNThings = new ArrayList<GroceryItem>();
for (int i=0; i < n; i++) {
firstNThings.add(this.groceries.get(i));
}
return firstNThings
}
public ArrayList<GroceryItem> getLastNThings(int n) {
ArrayList<GroceryItem> lastNThings = new ArrayList<GroceryItem>();
for (int i=this.groceries.size(); i < this.groceries.size()-n; i--) {
lastNThings.add(this.groceries.get(i-1);
}
return lastNThings;
}
}
公共杂货店列表表{
私营ArrayList杂货店;
公共杂货店(){
this.groceries=新的ArrayList();
}
公共阵列列表GetFirstInthings(int n){
ArrayList FirstInthings=新的ArrayList();
对于(int i=0;i所以我的问题是:这是一个问题吗?我应该重构任何东西吗?值得吗?优点是什么?如果在接口中定义了一个返回类型为原始类型的方法,但该方法的实际实现者返回各种参数化类型,我会遇到什么样的问题?如果IListable的两个方法都始终返回对于相同类型,请改用此选项:
public interface IListable<T> {
//returns first n items from list
public ArrayList<T> getFirstNThings(int n);
//returns last n items from list
public ArrayList<T> getLastNThings(int n);
}
公共接口表{
//返回列表中的前n项
公共ArrayList getFirstNThings(int n);
//返回列表中最后n个项目
公共数组列表getLastInthings(int n);
}
如果这不是一个选项,试着用?来代替。虽然基本上是一样的,但它避免了难看的警告
public interface IListable {
//returns first n items from list
public ArrayList<?> getFirstNThings(int n);
//returns last n items from list
public ArrayList<?> getLastNThings(int n);
}
公共接口表{
//返回列表中的前n项
公共ArrayList getFirstNThings(int n);
//返回列表中最后n个项目
公共数组列表getLastInthings(int n);
}
一般来说,在实现中使用比在超级类型或接口中更具体的返回类型不是问题。如果处理IListable,则需要处理返回列表中的任何对象类型。如果处理GroceryList,则只需要GroceryItems。这不仅适用于返回类型的Generic类型参数,而且还适用于因此,如果接口指定了
List get()
,则可以将其实现为ArrayList get()
最佳实践是永远不要在打开的代码中返回带有纯通配符的列表
,就像不应该返回null
一样
Java中的通配符泛型会给所有使用您的代码的程序员带来污染。您可以在关闭代码中解决本地问题
通常,您将避免返回协方差和逆变换通配符,如
list。此方法还允许您将GroceryList制作成一个完全通用类型的列表,以便以后重用。除了Sfussengenger所说的,我还更喜欢返回list
的方法,而不是ArrayList
。
public interface IListable {
//returns first n items from list
public ArrayList<?> getFirstNThings(int n);
//returns last n items from list
public ArrayList<?> getLastNThings(int n);
}