2015-08-16 116 views
0

我想学习Java中的通配符。在这里,我试图修改printCollection方法,以便它只会使用延伸AbstractList的类。它显示评论中的错误。我试图用一个ArrayList的对象,它工作正常。我正在使用Java 7.ArrayList的对象和抽象

import java.util.AbstractList; 
import java.util.ArrayList; 
import java.util.Collection; 
import java.util.List; 
import java.util.Set; 

public class Subtype { 
    void printCollection(Collection<? extends AbstractList<?>> c) { 
     for (Object e : c) { 
      System.out.println(e); 
     } 
    } 

    public static void main(String[] args) { 
     Subtype st= new Subtype(); 
     ArrayList<String> al = new ArrayList<String>(); 
     al.add("a"); 
     al.add("n"); 
     al.add("c"); 
     al.add("f"); 
     al.add("y"); 
     al.add("w"); 
     //The method printCollection(Collection<? extends AbstractList<?>>) in the type Subtype is not applicable for the 
     // arguments (ArrayList<String>) 
     st.printCollection(al); 
    } 

} 
+0

是否有一个特定的原因,你为什么只希望允许列表扩展'AbstractList'而不是所有实现'List'接口(契约)的列表?通过指定'AbstractList',您可以将代码耦合到特定的实现。只要有可能,你应该编码到接口而不是实现。 –

+0

@MickMnemonic谢谢我会牢记这一点。 –

回答

2

您正在询问AbstractList对象的集合,例如一个充满AbstractLists的列表。这真的是你想要的吗?

一个解决这将是这样......

<T extends AbstractList<?>> void printCollection(T c) { 

......这样一来,你的方法将只接受对象扩展AbstractLists任何通用内容。

但在其他评论者,海报和作家(布洛赫:有效的Jave,P134 +)已经正确地指出的那样,更好的风格应该简单地尝试这样的事:

void printCollection(AbstractList<?> c) { 
+0

谢谢你是对的,但我无法理解这是如何工作的 –

+0

我很抱歉,但我无法真正重复什么需要一本好书页面来解释这里。我建议引用一些Java泛型教程或书籍。 –

+0

我使用此链接阅读有关通配符https://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html –

2

在您的代码你假设参数应实现Collection并应包含扩展AbstractList

void printCollection(Collection<? extends AbstractList<?>> c) 

元素要得到你想要的,你可以简单地把它写这样的东西:

void printCollection(AbstractList<?> c) 
+1

我认为这是一个更好的答案。如果可能,在方法签名中使用有界通配符可以产生更灵活的API。 – scottb