程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 未支持的操作

未支持的操作

編輯:關於JAVA

利用static(靜態)數組Arrays.toList(),也許能將一個數組轉換成List,如下所示:
 

//: Unsupported.java
// Sometimes methods defined in the Collection
// interfaces don't work!
package c08.newcollections;
import java.util.*;

public class Unsupported {
  private static String[] s = {
    "one", "two", "three", "four", "five",
    "six", "seven", "eight", "nine", "ten",
  };
  static List a = Arrays.toList(s);
  static List a2 = Arrays.toList(
    new String[] { s[3], s[4], s[5] });
  public static void main(String[] args) {
    Collection1.print(a); // Iteration
    System.out.println(
      "a.contains(" + s[0] + ") = " + 
      a.contains(s[0]));
    System.out.println(
      "a.containsAll(a2) = " + 
      a.containsAll(a2));
    System.out.println("a.isEmpty() = " +
      a.isEmpty());
    System.out.println(
      "a.indexOf(" + s[5] + ") = " + 
      a.indexOf(s[5]));
    // Traverse backwards:
    ListIterator lit = a.listIterator(a.size());
    while(lit.hasPrevious())
      System.out.print(lit.previous());
    System.out.println();
    // Set the elements to different values:
    for(int i = 0; i < a.size(); i++)
      a.set(i, "47");
    Collection1.print(a);
    // Compiles, but won't run:
    lit.add("X"); // Unsupported operation
    a.clear(); // Unsupported
    a.add("eleven"); // Unsupported
    a.addAll(a2); // Unsupported
    a.retainAll(a2); // Unsupported
    a.remove(s[0]); // Unsupported
    a.removeAll(a2); // Unsupported
  }
} ///:~

從中可以看出,實際只實現了Collection和List接口的一部分。剩余的方法導致了不受歡迎的一種情況,名為UnsupportedOperationException。在下一章裡,我們會講述違例的詳細情況,但在這裡有必要進行一下簡單說明。這裡的關鍵在於“集合接口”,以及新集合庫內的另一些接口,它們都包含了“可選的”方法。在實現那些接口的集合類中,或者提供、或者沒有提供對那些方法的支持。若調用一個未獲支持的方法,就會導致一個UnsupportedOperationException(操作未支持違例),這表明出現了一個編程錯誤。
大家或許會覺得奇怪,不是說“接口”和基礎類最大的“賣點”就是它們許諾這些方法能產生一些有意義的行為嗎?上述違例破壞了那個許諾——它調用的一部分方法不僅不能產生有意義的行為,而且還會中止程序的運行。在這些情況下,類型的所謂安全保證似乎顯得一錢不值!但是,情況並沒有想象的那麼壞。通過Collection,List,Set或者Map,編譯器仍然限制我們只能調用那個接口中的方法,所以它和Smalltalk還是存在一些區別的(在Smalltalk中,可為任何對象調用任何方法,而且只有在運行程序時才知道這些調用是否可行)。除此以外,以Collection作為自變量的大多數方法只能從那個集合中讀取數據——Collection的所有“read”方法都不是可選的。
這樣一來,系統就可避免在設計期間出現接口的沖突。而在集合庫的其他設計方案中,最終經常都會得到數量過多的接口,用它們描述基本方案的每一種變化形式,所以學習和掌握顯得非常困難。有些時候,甚至難於捕捉接口中的所有特殊情況,因為人們可能設計出任何新接口。但Java的“不支持的操作”方法卻達到了新集合庫的一個重要設計目標:易於學習和使用。但是,為了使這一方法真正有效,卻需滿足下述條件:
(1) UnsupportedOperationException必須屬於一種“非常”事件。也就是說,對於大多數類來說,所有操作都應是可行的。只有在一些特殊情況下,一、兩個操作才可能未獲支持。新集合庫滿足了這一條件,因為絕大多數時候用到的類——ArrayList,LinkedList,HashList和HashMap,以及其他集合方案——都提供了對所有操作的支持。但是,如果想新建一個集合,同時不想為集合接口中的所有方法都提供有意義的定義,同時令其仍與現有庫配合,這種設計方法也確實提供了一個“後門”可以利用。
(2) 若一個操作未獲支持,那麼UnsupportedOperationException(未支持的操作違例)極有可能在實現期間出現,則不是在產品已交付給客戶以後才會出現。它畢竟指出的是一個編程錯誤——不正確地使用了一個類。這一點不能十分確定,通過也可以看出這種方案的“試驗”特征——只有經過多次試驗,才能找出最理想的工作方式。

在上面的例子中,Arrays.toList()產生了一個List(列表),該列表是由一個固定長度的數組後推出來的。因此唯一能夠支持的就是那些不改變數組長度的操作。在另一方面,若請求一個新接口表達不同種類的行為(可能叫作“FixedSizeList”——固定長度列表),就有遭遇更大的復雜程度的危險。這樣一來,以後試圖使用庫的時候,很快就會發現自己不知從何處下手。
對那些采用Collection,List,Set或者Map作為參數的方法,它們的文檔應當指出哪些可選的方法是必須實現的。舉個例子來說,排序要求實現set()和Iterator.set()方法,但不包括add()和remove()。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved