2014-10-27 34 views
0

我主要看到任何代码始终通过其接口类型(例如Set)引用集合,而不是通过其实现类型。该代码通过其接口类型(例如,Set)而不是其实现类型来引用集合

下面是由Oracle's Java Tutorial提供的原因,

这是一个强烈建议的编程习惯,因为它可以让你 的灵活性,通过改变构造仅仅改变实施。 如果用于存储集合的变量或使用 传递它的参数声明为集合的实现类型 而不是其接口类型,则所有此类变量和参数必须更改为 才能更改其集合实现类型。

此外,作者提供了不能保证生成的程序能够正常工作。如果程序使用任何非标准操作存在于原始实现类型不是在新,该程序将失败。仅通过界面引用集合可以防止使用任何非标准操作。

作者谈论的非标准操作是什么?其次,如何仅仅通过界面引用集合防止我们使用任何非标准操作?

请在Java代码的帮助下详细说明吗?

+0

该示例位于您找到它的同一页面上。 http://docs.oracle.com/javase/tutorial/collections/interfaces/set.html他们已经在这个例子中使用了Set。 – ha9u63ar 2014-10-27 11:34:57

回答

5

对此的一个示例是LinkedList,其具有getFirst()getLast()方法。使用它们看起来很方便,但如果实施更改为ArrayList,它们就消失了。

1

通过初始化接口和实例有多个优点。

List list = new Arraylist(); 

现在你有一个列表对象,它可以在稍后对实现List接口的任何类有用。

但是,一旦你有ArrayList arraylist = new ArrayList()你将失去​​这样的机会。

0

即使在使用接口时,您仍需要考虑一个缺陷。

考虑下面的代码:

public void sampleMethod(List<String> list) { 
    list.add("baz"); 

    System.out.println(list); 
} 

我们正在使用接口定义唯一非标准操作,但如果你检查documentation,你会发现,add()操作是可选的。

所以,如果你执行下面的代码

public void test() { 
    List<String> sampleList = new ArrayList<>(); 
    sampleList.add("foo"); 

    try { 
     sampleMethod(sampleList); 
    }catch (Exception e) { 
     e.printStackTrace(); 
    } 

    try { 
     sampleMethod(Collections.unmodifiableList(sampleList)); 
    }catch (Exception e) { 
     e.printStackTrace(); 
    } 

    try { 
     sampleMethod(Collections.singletonList("bar")); 
    }catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

您将获得:

[foo, baz] 
java.lang.UnsupportedOperationException 
    at java.util.Collections$UnmodifiableCollection.add(Collections.java:1075) 
    ... 
java.lang.UnsupportedOperationException 
    at java.util.AbstractList.add(AbstractList.java:148) 
    ... 

这是一个例子,为什么即使你只使用非标准操作你的程序可能会失败。

相关问题