java™ 5 擴展了 Java 語言類型系統(tǒng)以支持類、方法和值的參數(shù)化類型。參數(shù)化的類型通過確保使用正確的類型及消除從源代碼進行類型轉(zhuǎn)換提供了重要的編譯時好處。除了這些編譯時好處,類型信息對于 classworking 工具操縱 Java 代碼也有幫助。在本文中,JiBX 首席開發(fā)員 Dennis Sosnoski 分析了如何用反射深入?yún)?shù)化類型的內(nèi)部,并充分展示了 Java 5 應(yīng)用程序數(shù)據(jù)結(jié)構(gòu)的優(yōu)勢。
許多工具都是圍繞使用 Java 反射而設(shè)計的,它們的用途包括從用數(shù)據(jù)值填充 GUI 組件到在運行的應(yīng)用程序中動態(tài)裝載新功能。反射對于在運行時分析數(shù)據(jù)結(jié)構(gòu)非凡有用,許多在內(nèi)部對象結(jié)構(gòu)與外部格式(包括 xml、數(shù)據(jù)庫和其他持久化格式)之間轉(zhuǎn)換的框架都基于對數(shù)據(jù)結(jié)構(gòu)的反射分析。
使用反射分析數(shù)據(jù)結(jié)構(gòu)的一個問題是標準 Java 集合類(如 java.util.ArrayList)對于反射來說總是“死胡同(dead-end)” —— 到達一個集合類后,無法再訪問數(shù)據(jù)結(jié)構(gòu)的更多細節(jié),因為沒有關(guān)于集合中包含的項目類型的信息。Java 5 改變了這一情況,它增加了對泛型的支持,將所有集合類轉(zhuǎn)換為支持類型的泛型形式。Java 5 還擴展了反射 API ,支持在運行時對泛型類型信息進行訪問。這些改變使反射可以比以往更深入地挖掘數(shù)據(jù)結(jié)構(gòu)。
包裝之下代碼
許多文章討論了 Java 5 的泛型功能的使用。對于本文,假定您已經(jīng)了解泛型的基本知識。我們首先使用一些示例代碼,然后直接討論如何在運行時訪問泛型信息。
作為使用泛型的一個例子,我預(yù)備使用一個表示一組路徑中的目錄和文件的數(shù)據(jù)結(jié)構(gòu)。清單 1 給出了這個數(shù)據(jù)結(jié)構(gòu)根類的代碼。PathDirectory 類取路徑 String 數(shù)組作為構(gòu)造函數(shù)參數(shù)。這個構(gòu)造函數(shù)將每一個字符串解釋為目錄路徑,并構(gòu)造一個數(shù)據(jù)結(jié)構(gòu)以表示這個路徑下面的文件和子目錄。處理每一路徑時,這個構(gòu)造函數(shù)就將這個路徑和這個路徑的數(shù)據(jù)結(jié)構(gòu)加到一個成對集合(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(); } }}
新聞熱點
疑難解答