欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Classworking 工具箱: 反射泛型

泛型增加了 classworking 工具可以使用的類(lèi)型信息

Java™ 5 擴展了 Java 語(yǔ)言類(lèi)型系統以支持類(lèi)、方法和值的參數化類(lèi)型。參數化的類(lèi)型通過(guò)確保使用正確的類(lèi)型及消除從源代碼進(jìn)行類(lèi)型轉換提供了重要的編譯時(shí)好處。除了這些編譯時(shí)好處,類(lèi)型信息對于 classworking 工具操縱 Java 代碼也有幫助。在本文中,JiBX 首席開(kāi)發(fā)員 Dennis Sosnoski 分析了如何用反射深入參數化類(lèi)型的內部,并充分展示了 Java 5 應用程序數據結構的優(yōu)勢。

許多工具都是圍繞使用 Java 反射而設計的,它們的用途包括從用數據值填充 GUI 組件到在運行的應用程序中動(dòng)態(tài)裝載新功能。反射對于在運行時(shí)分析數據結構特別有用,許多在內部對象結構與外部格式(包括 XML、數據庫和其他持久化格式)之間轉換的框架都基于對數據結構的反射分析。

使用反射分析數據結構的一個(gè)問(wèn)題是標準 Java 集合類(lèi)(如 java.util.ArrayList)對于反射來(lái)說(shuō)總是“死胡同(dead-end)” —— 到達一個(gè)集合類(lèi)后,無(wú)法再訪(fǎng)問(wèn)數據結構的更多細節,因為沒(méi)有關(guān)于集合中包含的項目類(lèi)型的信息。Java 5 改變了這一情況,它增加了對泛型的支持,將所有集合類(lèi)轉換為支持類(lèi)型的泛型形式。Java 5 還擴展了反射 API ,支持在運行時(shí)對泛型類(lèi)型信息進(jìn)行訪(fǎng)問(wèn)。這些改變使反射可以比以往更深入地挖掘數據結構。

包裝之下代碼

許多文章討論了 Java 5 的泛型功能的使用(包括 參考資料 中的鏈接)。對于本文,假定您已經(jīng)了解泛型的基本知識。我們首先使用一些示例代碼,然后直接討論如何在運行時(shí)訪(fǎng)問(wèn)泛型信息。

作為使用泛型的一個(gè)例子,我準備使用一個(gè)表示一組路徑中的目錄和文件的數據結構。清單 1 給出了這個(gè)數據結構根類(lèi)的代碼。PathDirectory 類(lèi)取路徑 String 數組作為構造函數參數。這個(gè)構造函數將每一個(gè)字符串解釋為目錄路徑,并構造一個(gè)數據結構以表示這個(gè)路徑下面的文件和子目錄。處理每一路徑時(shí),這個(gè)構造函數就將這個(gè)路徑和這個(gè)路徑的數據結構加到一個(gè)成對集合(pair collection)中。


清單 1. 目錄信息集

public class PathDirectory implements Iterable<String>{    private final PairCollection<String, DirInfo> m_pathPairs;        public PathDirectory(String[] paths) {        m_pathPairs = new PairCollection<String, DirInfo>();        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<String, DirInfo>.PairIterator iterator() {        return m_pathPairs.iterator();    }        public static void main(String[] args) {        PathDirectory inst = new PathDirectory(args);        PairCollection<String, DirInfo>.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<T,U> 的代碼。這個(gè)泛型類(lèi)處理成對的值,類(lèi)型參數給出了這些對中項目的類(lèi)型。它提供了一個(gè) add() 方法向集合中加入一個(gè)元組(tuple),一個(gè) clear() 方法清空集合中所有元組,一個(gè) iterator() 方法返回遍歷集合中所有對的迭代器。內部 PairIterator 類(lèi)實(shí)現由后一個(gè)方法返回的特殊迭代器,它定義了一個(gè)額外的 matching() 方法,這個(gè)方法用于得到由標準 next() 方法返回的值的配對(第二個(gè))值。


清單 2. 泛型對集合

public class PairCollection<T,U> implements Iterable<T>{    // code assumes random access so force implementation class	  private final ArrayList<T> m_tValues;    private final ArrayList<U> m_uValues;        public PairCollection() {		    m_tValues = new ArrayList<T>();        m_uValues = new ArrayList<U>();    }        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<T>    {        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();        }    }}

PairCollection<T,U> 對于包含值的實(shí)際集合在內部使用泛型。它用第一個(gè)參數類(lèi)型實(shí)現了 java.lang.Iterable 接口,從而可以直接在新型 for 循環(huán)中使用以遍歷每對中的第一個(gè)值。不幸的是,在使用新型 for 循環(huán)時(shí),無(wú)法訪(fǎng)問(wèn)實(shí)際的迭代器,因而無(wú)法獲取每一對的第二個(gè)值。這就是為什么 清單 1 中的 main() 測試方法使用 while 循環(huán)而不是一個(gè)新的 for 循環(huán)。

清單 3 給出了包含目錄和文件信息的一對類(lèi)的代碼。DirInfo 類(lèi)使用有類(lèi)型的 java.util.List 集合表示普通文件和目錄的子目錄。構造函數將這些集合創(chuàng )建為不可修改的列表,使得它們可以安全地直接返回。FileInfo 類(lèi)更簡(jiǎn)單,只包含文件名和最后修改日期。


清單 3. 目錄和文件數據類(lèi)

public class DirInfo{    private final List<FileInfo> m_files;    private final List<DirInfo> m_directories;    private final Date m_lastModify;        public DirInfo(File dir) {        m_lastModify = new Date(dir.lastModified());        File[] childs = dir.listFiles();        List<FileInfo> files = new ArrayList<FileInfo>();        List<DirInfo> dirs = new ArrayList<DirInfo>();        for (int i = 0; i < childs.length; i++) {            File child = childs[i];            if (child.isDirectory()) {                dirs.add(new DirInfo(child));            } else if (child.isFile()) {                files.add(new FileInfo(child));            }        }        m_files = Collections.unmodifiableList(files);        m_directories = Collections.unmodifiableList(dirs);    }        public List<DirInfo> getDirectories() {        return m_directories;    }    public List<FileInfo> getFiles() {        return m_files;    }    public Date getLastModify() {        return m_lastModify;    }}public class FileInfo{    private final String m_name;    private final Date m_lastModify;        public FileInfo(File file) {        m_name = file.getName();        m_lastModify = new Date(file.lastModified());    }    public Date getLastModify() {        return m_lastModify;    }    public String getName() {        return m_name;    }}

清單 4 給出了 清單 1 中的 main() 方法的運行示例:


清單 4. 示例運行

[dennis]$ java -cp . com.sosnoski.generics.PathDirectory   /home/dennis/bin /home/dennis/xtools /home/dennis/docs/businessDirectory /home/dennis/bin has 31 files and 0 child directoriesDirectory /home/dennis/xtools has 0 files and 3 child directoriesDirectory /home/dennis/docs/business has 34 files and 34 child directories




泛型反射

泛型是在 Java 平臺上作為編譯時(shí)轉換實(shí)現的。編譯器實(shí)際上生成與使用非泛型源代碼時(shí)相同的字節指令,插入運行時(shí)類(lèi)型轉換以在每次訪(fǎng)問(wèn)時(shí)將值轉換為正確的類(lèi)型。盡管是相同的字節碼,但是類(lèi)型參數信息 一個(gè)新的簽名(signature) 屬性記錄在類(lèi)模式中。JVM 在裝載類(lèi)時(shí)記錄這個(gè)簽名信息,并在運行時(shí)通過(guò)反射使它可用。在這一節,我將深入挖掘反射 API 如何使類(lèi)型信息可用的細節。

類(lèi)型反射接口

通過(guò)反射訪(fǎng)問(wèn)類(lèi)型參數信息有些復雜。首先,需要有一個(gè)具有所提供類(lèi)型信息的字段(或者其他可提供類(lèi)型的辦法,如方法參數或者返回類(lèi)型)。然后可以用 Java 5 新增的 getGenericType() 方法從這個(gè)字段的 java.lang.reflect.Field 實(shí)例提取特定于泛型的信息。這個(gè)新方法返回一個(gè) java.lang.reflect.Type 實(shí)例。

惟一的問(wèn)題是 Type 是一個(gè)沒(méi)有方法的接口。在實(shí)例化后,需要檢查擴展了 Type 的子接口以了解得到的是什么(以及如何使用它)。Javadocs 列出了四種子接口,我會(huì )依次介紹它們。為了方便,我在清單 5 中給出了接口定義。它們都包括在 java.lang.reflect 包中。


清單 5. Type 子接口

interface GenericArrayType extends Type {    Type getGenericComponentType();}interface ParameterizedType extends Type {    Type[] getActualTypeArguments();    Type getOwnerType();    Type getRawType();}interface TypeVariable<D extends GenericDeclaration> extends Type {    Type[] getBounds();    D getGenericDeclaration();    String getName();}interface WildcardType extends Type {    Type[] getLowerBounds();    Type[] getUpperBounds();}

java.lang.reflect.GenericArrayType 是第一個(gè)子接口。這個(gè)子接口提供了關(guān)于數組類(lèi)型的信息,數組的組件類(lèi)型可以是參數化的,也可以是一個(gè)類(lèi)型變量。只定義了一個(gè)方法 getGenericComponentType(),它返回數組組件 Type。

java.lang.reflect.ParameterizedTypeType 的第二個(gè)子接口。它提供了關(guān)于具有特定類(lèi)型參數的泛型類(lèi)型的信息。這個(gè)接口定義了三個(gè)方法,其中最讓人感興趣的(對于本文來(lái)說(shuō))是 getActualTypeArguments() 方法。這個(gè)方法返回一個(gè) (drum role)數組 . . .還有更多的 Type 實(shí)例。返回的 Type 表示原來(lái)(未參數化的)類(lèi)型的實(shí)際類(lèi)型參數。

Type 的第三個(gè)子接口是 java.lang.reflect.TypeVariable<D extands GenericDeclaration>。這個(gè)接口給出了表示一個(gè)參數類(lèi)型的變量(如這個(gè)類(lèi)型名中變量 "D")的細節。這個(gè)接口定義了三個(gè)方法:getBounds(),它返回(您猜) Type 實(shí)例數組;getGenericDeclaration(),它返回對應于類(lèi)型變量聲明的 java.lang.reflect.GenericDeclaration 接口的實(shí)例;getName(),它返回類(lèi)型變量在源代碼中使用的名字。這些方法都需要進(jìn)一步說(shuō)明。因此我將逐一分析它們。

getBounds() 方法返回的類(lèi)型數組定義對于變量的類(lèi)型所施加的限制。這些限制在源代碼中作為在模板變量中以 extends B(其中 “B” 是某種類(lèi)型)的格式添加的子句進(jìn)行聲明。很方便, java.lang.reflect.TypeVariable<D extends GenericDeclaration> 本身就給出了這種形式的上界定義的一個(gè)例子 —— java.lang.reflect.GenericDeclaration 是類(lèi)型參數 “D” 的上界,意味著(zhù) “D” 必須是擴展或者實(shí)現 GenericDeclaration 的類(lèi)型。

getGenericDeclaration() 方法提供了一種訪(fǎng)問(wèn)聲明了 TypeVariableGenericDeclaration 實(shí)例的方式。在標準 Java API 中有三個(gè)類(lèi)實(shí)現了 GenericDeclarationjava.lang.Class、java.lang.reflect.Constructorjava.lang.reflect.Method。這三個(gè)類(lèi)是有意義的,因為參數類(lèi)型只能在類(lèi)、構造函數和方法中聲明。GenericDeclaration 接口定義了一個(gè)方法,它返回在聲明中包含的 TypeVariable 的數組。

getName() 方法只是返回與源代碼中給出的完全一樣的類(lèi)型變量名。

java.lang.reflect.WildcardTypeType 的第四個(gè)(也是最后一個(gè))子接口。WildcardType 只定義了兩個(gè)方法,返回通配類(lèi)型的下界和上界。在前面,我給出了上界的一個(gè)例子,下界也類(lèi)似,但是它們是通過(guò)指定一種類(lèi)型而定義的,提供的類(lèi)型必須是它的超接口或者超類(lèi)。

對一個(gè)例子的反射

我在上一節中描述的反射接口提供了解碼泛型信息的鉤子,但是確定它們有點(diǎn)難度 —— 不管從哪兒開(kāi)始,每件事都像是循環(huán)并回到 java.lang.reflect.Type。為了展示它們是如何工作的,我將利用 清單 1 代碼中的一個(gè)例子并對它進(jìn)行反射。

首先,我嘗試訪(fǎng)問(wèn) 清單 1m_pathPairs 字段的類(lèi)型信息。清單 6 中的代碼得到這個(gè)字段的泛型類(lèi)型,檢查結果是否為所預期的類(lèi)型,然后列出原始類(lèi)型和參數化類(lèi)型的實(shí)際類(lèi)型參數。在清單 6 的最后以粗體顯示了運行這段代碼的輸出:


清單 6. 第一個(gè)反射代碼

public static void main(String[] args) throws Exception {        // get the basic information    Field field =        PathDirectory.class.getDeclaredField("m_pathPairs");    Type gtype = field.getGenericType();    if (gtype instanceof ParameterizedType) {                // list the raw type information        ParameterizedType ptype = (ParameterizedType)gtype;        Type rtype = ptype.getRawType();        System.out.println("rawType is instance of " +            rtype.getClass().getName());        System.out.println(" (" + rtype + ")");                // list the actual type arguments        Type[] targs = ptype.getActualTypeArguments();        System.out.println("actual type arguments are:");        for (int j = 0; j < targs.length; j++) {            System.out.println(" instance of " +                targs[j].getClass().getName() + ":");            System.out.println("  (" + targs[j] + ")");        }    } else {        System.out.println            ("getGenericType is not a ParameterizedType!");    }}rawType is instance of java.lang.Class (class com.sosnoski.generics.PairCollection)actual type arguments are: instance of java.lang.Class:  (class java.lang.String) instance of java.lang.Class:  (class com.sosnoski.generics.DirInfo)

到目前為止一切都好。m_pathPairs 字段定義為 PairCollection<String, DirInfo> 類(lèi)型,它匹配反射所訪(fǎng)問(wèn)的類(lèi)型信息。不過(guò)深入實(shí)際的參數化類(lèi)型定義會(huì )有些復雜;返回的 Type 實(shí)例是一個(gè)沒(méi)有實(shí)現任何 Type 子接口的 java.lang.Class 對象。幸運的是,Java 5 Class<T> 類(lèi)本身提供了一個(gè)深入泛型類(lèi)定義的細節的方法。這個(gè)方法是 getTypeParameters(),它返回一個(gè) TypeVariable<Class<T>> 數組。在清單 7 中,我修改了 清單 6 的代碼以使用這個(gè)方法,得到的結果同樣以粗體顯示在代碼中:


清單 7. 深入參數化類(lèi)型

public static void main(String[] args) throws Exception {        // get the basic information    Field field =        PathDirectory.class.getDeclaredField("m_pathPairs");    ParameterizedType ptype =        (ParameterizedType)field.getGenericType();    Class rclas = (Class)ptype.getRawType();    System.out.println("rawType is class " + rclas.getName());        // list the type variables of the base class    TypeVariable[] tvars = rclas.getTypeParameters();    for (int i = 0; i < tvars.length; i++) {        TypeVariable tvar = tvars[i];        System.out.print(" Type variable " +            tvar.getName() + " with upper bounds [");        Type[] btypes = tvar.getBounds();        for (int j = 0; j < btypes.length; j++) {            if (j > 0) {                System.out.print(" ");            }            System.out.print(btypes[j]);        }        System.out.println("]");    }        // list the actual type arguments    Type[] targs = ptype.getActualTypeArguments();    System.out.print("Actual type arguments are\n (");    for (int j = 0; j < targs.length; j++) {        if (j > 0) {            System.out.print(" ");        }        Class tclas = (Class)targs[j];        System.out.print(tclas.getName());    }    System.out.print(")");}rawType is class com.sosnoski.generics.PairCollection Type variable T with upper bounds [class java.lang.Object] Type variable U with upper bounds [class java.lang.Object]Actual type arguments are (java.lang.String com.sosnoski.generics.DirInfo)

清單 7 的結果顯示了解碼的結構。實(shí)際的類(lèi)型參數可以由泛型類(lèi)定義的類(lèi)型變量匹配。在下一節,我將做此工作作為遞推泛型解碼方法的一部分。




泛型遞推

在上一節,我快速完成了訪(fǎng)問(wèn)泛型信息的反射方法?,F在我將用這些方法構建一個(gè)解釋泛型的遞推處理程序。清單 8 給出了相關(guān)的代碼:


清單 8. 遞推泛型分析

public class Reflect{    private static HashSet<String> s_processed = new HashSet<String>();        private static void describe(String lead, Field field) {                // get base and generic types, check kind        Class<?> btype = field.getType();        Type gtype = field.getGenericType();        if (gtype instanceof ParameterizedType) {                        // list basic parameterized type information            ParameterizedType ptype = (ParameterizedType)gtype;            System.out.println(lead + field.getName() +                " is of parameterized type");            System.out.println(lead + ‘ ‘ + btype.getName());                        // print list of actual types for parameters            System.out.print(lead + " using types (");            Type[] actuals = ptype.getActualTypeArguments();            for (int i = 0; i < actuals.length; i++) {                if (i > 0) {                    System.out.print(" ");                }                Type actual = actuals[i];                if (actual instanceof Class) {                    System.out.print(((Class)actual).getName());                } else {                    System.out.print(actuals[i]);                }            }            System.out.println(")");                        // analyze all parameter type classes            for (int i = 0; i < actuals.length; i++) {                Type actual = actuals[i];                if (actual instanceof Class) {                    analyze(lead, (Class)actual);                }            }                    } else if (gtype instanceof GenericArrayType) {                        // list array type and use component type            System.out.println(lead + field.getName() +                " is array type " + gtype);            gtype = ((GenericArrayType)gtype).                getGenericComponentType();                    } else {                        // just list basic information            System.out.println(lead + field.getName() +                " is of type " + btype.getName());        }                // analyze the base type of this field        analyze(lead, btype);    }        private static void analyze(String lead, Class<?> clas) {                // substitute component type in case of an array        if (clas.isArray()) {            clas = clas.getComponentType();        }                // make sure class should be expanded        String name = clas.getName();        if (!clas.isPrimitive() && !clas.isInterface() &&            !name.startsWith("java.lang.") &&            !s_processed.contains(name)) {                        // print introduction for class            s_processed.add(name);            System.out.println(lead + "Class " +                clas.getName() + " details:");                        // process each field of class            String indent = lead + ‘ ‘;            Field[] fields = clas.getDeclaredFields();            for (int i = 0; i < fields.length; i++) {                Field field = fields[i];                if (!Modifier.isStatic(field.getModifiers())) {                    describe(indent, field);                }            }        }    }        public static void main(String[] args) throws Exception {        analyze("", PathDirectory.class);    }}

清單 8 中的代碼使用兩個(gè)相互遞推的方法進(jìn)行實(shí)際的分析。analyze() 方法取一個(gè)類(lèi)作為參數,通過(guò)對每個(gè)字段的定義進(jìn)行必要的處理展開(kāi)這個(gè)類(lèi)。describe() 方法打印特定字段的類(lèi)型信息的描述,對在這一過(guò)程中它遇到的每一個(gè)類(lèi)調用 analyze()。每個(gè)方法還有一個(gè)給出當前縮進(jìn)字符串的參數,它使每一級類(lèi)嵌套都縮進(jìn)一些空間。

清單 9 給出了用 清單 8 中的代碼分析 清單 1、清單 2清單 3 中代碼的完整結構所生成的輸出。


清單 9. 泛型示例代碼的分析

Class com.sosnoski.generics.PathDirectory details: m_pathPairs is of parameterized type  com.sosnoski.generics.PairCollection  using types (java.lang.String com.sosnoski.generics.DirInfo) Class com.sosnoski.generics.DirInfo details:  m_files is of parameterized type   java.util.List   using types (com.sosnoski.generics.FileInfo)  Class com.sosnoski.generics.FileInfo details:   m_name is of type java.lang.String   m_lastModify is of type java.util.Date   Class java.util.Date details:    fastTime is of type long    cdate is of type sun.util.calendar.BaseCalendar$Date    Class sun.util.calendar.BaseCalendar$Date details:     cachedYear is of type int     cachedFixedDateJan1 is of type long     cachedFixedDateNextJan1 is of type long  m_directories is of parameterized type   java.util.List   using types (com.sosnoski.generics.DirInfo)  m_lastModify is of type java.util.Date Class com.sosnoski.generics.PairCollection details:  m_tValues is of parameterized type   java.util.ArrayList   using types (T)  Class java.util.ArrayList details:   elementData is array type E[]   size is of type int  m_uValues is of parameterized type   java.util.ArrayList   using types (U)

清單 9 的輸出給出了泛型類(lèi)型是如何參數化使用的基本情況,包括為在 DirInfo 類(lèi)中列出的 m_filesm_directories 項指定的類(lèi)型。但當涉及到 PairCollection 類(lèi)(在底部)時(shí),字段類(lèi)型只是作為變量給出。對這個(gè)字段只顯示為變量的原因是由反射提供的泛型類(lèi)型信息不處理替換 —— 而是由反射代碼的使用者處理泛型類(lèi)中的替換。這項工作并不太困難,因為可以從清單 9 的輸出中進(jìn)行猜測。這里 m_tValues 展開(kāi)的細節顯示 ArrayList 是用 “T” 類(lèi)型參數化的,而嵌套的 ArrayList 展開(kāi)顯示 elementData 字段是用類(lèi)型 “E” 參數化的。要在每一個(gè)實(shí)例中正確關(guān)聯(lián)這些類(lèi)型,需要在展開(kāi)的每一階段跟蹤類(lèi)型變量實(shí)際被替換的類(lèi)型(如前所述,可用 java.lang.Class.getTypeParameters() 方法得到)。在這里,這意味著(zhù)在 PairCollection 展開(kāi)中的 “T” 和 m_tValuesArrayList 展開(kāi)中的 “E” 替換 java.lang.String。我不再給出更多的清單,而是將變化細節留給您。




更多的泛型內容

我已在本文中展示了如何在運行時(shí)挖掘已編譯類(lèi)的泛型類(lèi)型信息(至少是基本的,我忽略了像內部類(lèi)這樣的復雜情況以及泛型中一些更復雜的結構)。

作為一個(gè)示例應用程序,我準備使用泛型類(lèi)型信息改進(jìn)我的 JiBX XML 數據綁定框架中提供的默認綁定生成器?,F在綁定生成器不知道在 Java 集合(或者其他無(wú)類(lèi)型的引用)中出現的是什么樣的內容,因此生成器讓用戶(hù)修改生成的綁定并增加相應的內容;加入泛型反射代碼后,對于使用 Java 5 的用戶(hù),生成器將可以從泛型中直接得到類(lèi)型信息。

但是在 JVM 中裝載類(lèi)以訪(fǎng)問(wèn)泛型類(lèi)型信息并不總是方便的。對于 JiBX,處理類(lèi)時(shí)最重要的部分是向編譯的類(lèi)表示中加入字節碼。為此,JiBX 使用了一個(gè)字節碼操縱框架(在 JiBX 中是 BCEL,在 JiBX 2.0 中改為 ASM)。對于 JiBX 來(lái)說(shuō),幸運的是,ASM 框架包含在解析二進(jìn)制類(lèi)表示時(shí)訪(fǎng)問(wèn)同樣的類(lèi)型信息的鉤子,而且可以在生成新類(lèi)時(shí)添加泛型類(lèi)型信息。下個(gè)月,我將介紹 ASM 的分析方式并與在本月討論的反射支持進(jìn)行比較。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
在舊版 JVM 上使用 J2SE 5.0 特性
Java Annotation入門(mén)
深入Java關(guān)鍵字null
oracle數據類(lèi)型和對應的java類(lèi)型
(一)Class類(lèi),獲取類(lèi)信息
J2EE第二十天??Java?Annotation注解
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久