2014-10-27 41 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) 
    ... 

這是一個例子,爲什麼即使你只使用非標準操作你的程序可能會失敗。

相關問題