java™ 5 擴展了 Java 語言類型系統以支持類、方法和值的參數化類型。參數化的類型通過確保使用正確的類型及消除從源代碼進行類型轉換提供了重要的編譯時好處。除了這些編譯時好處,類型信息對于 classworking 工具操縱 Java 代碼也有幫助。在本文中,JiBX 首席開發員 Dennis Sosnoski 分析了如何用反射深入參數化類型的內部,并充分展示了 Java 5 應用程序數據結構的優勢。
許多工具都是圍繞使用 Java 反射而設計的,它們的用途包括從用數據值填充 GUI 組件到在運行的應用程序中動態裝載新功能。反射對于在運行時分析數據結構非凡有用,許多在內部對象結構與外部格式(包括 xml、數據庫和其他持久化格式)之間轉換的框架都基于對數據結構的反射分析。
使用反射分析數據結構的一個問題是標準 Java 集合類(如 java.util.ArrayList)對于反射來說總是“死胡同(dead-end)” —— 到達一個集合類后,無法再訪問數據結構的更多細節,因為沒有關于集合中包含的項目類型的信息。Java 5 改變了這一情況,它增加了對泛型的支持,將所有集合類轉換為支持類型的泛型形式。Java 5 還擴展了反射 API ,支持在運行時對泛型類型信息進行訪問。這些改變使反射可以比以往更深入地挖掘數據結構。
包裝之下代碼
許多文章討論了 Java 5 的泛型功能的使用。對于本文,假定您已經了解泛型的基本知識。我們首先使用一些示例代碼,然后直接討論如何在運行時訪問泛型信息。
作為使用泛型的一個例子,我預備使用一個表示一組路徑中的目錄和文件的數據結構。清單 1 給出了這個數據結構根類的代碼。PathDirectory 類取路徑 String 數組作為構造函數參數。這個構造函數將每一個字符串解釋為目錄路徑,并構造一個數據結構以表示這個路徑下面的文件和子目錄。處理每一路徑時,這個構造函數就將這個路徑和這個路徑的數據結構加到一個成對集合(pair collection)中。
清單 1. 目錄信息集
public class PathDirectory implements Iterable{ PRivate final PairCollection m_pathPairs; public PathDirectory(String[] paths) { m_pathPairs = new PairCollection (); for (String path : paths) { File file = new File(path); if (file.exists() && file.isDirectory()) { DirInfo info = new DirInfo(new File(path)); m_pathPairs.add(path, info); } } } public PairCollection .PairIterator iterator() { return m_pathPairs.iterator(); } public static void main(String[] args) { PathDirectory inst = new PathDirectory(args); PairCollection .PairIterator iter = inst.iterator(); while (iter.hasNext()) { String path = iter.next(); DirInfo info = iter.matching(); System.out.println("Directory " + path + " has " + info.getFiles().size() + " files and " + info.getDirectories().size() + " child directories"); } }}
清單 2 給出了 PairCollection
清單 2. 泛型對集合
public class PairCollectionimplements Iterable { // code assumes random access so force implementation class private final ArrayList m_tValues; private final ArrayList m_uValues; public PairCollection() { m_tValues = new ArrayList (); m_uValues = new ArrayList(); } public void add(T t, U u) { m_tValues.add(t); m_uValues.add(u); } public void clear() { m_tValues.clear(); m_uValues.clear(); } public PairIterator iterator() { return new PairIterator(); } public class PairIterator implements Iterator { private int m_offset; public boolean hasNext() { return m_offset < m_tValues.size(); } public T next() { if (m_offset < m_tValues.size()) { return m_tValues.get(m_offset++); } else { throw new NoSUChElementException(); } } public U matching() { if (m_offset > 0) { return m_uValues.get(m_offset-1); } else { throw new NoSuchElementException(); } } public void remove() { throw new UnsupportedOperationException(); } }}
新聞熱點
疑難解答