63
Reflection & Generics in JDK1.5 侯侯 / J.J. Hou 資資資資 / 資資資資 / 資資資資 [email protected], http://www.jjhou.com

Reflection & Generics in JDK1.5

Embed Size (px)

DESCRIPTION

Reflection & Generics in JDK1.5. 侯捷 / J.J. Hou 資訊教育 / 專欄執筆 / 大學教師 [email protected], http://www.jjhou.com. Generics. 講題提要. Generics. 自JDK1.3起, Generics 技術以各種 外掛 方式進入Java。JDK1.5正式 內建 此一技術,對 Java 及其 Library 帶來全面的影響與改寫。本講題追蹤該技術全面進入 JDK1.5 的狀況。. Reflection. 講題提要. Reflection. - PowerPoint PPT Presentation

Citation preview

Page 1: Reflection & Generics in JDK1.5

Reflection & Generics in JDK1.5

侯捷 / J.J. Hou資訊教育 / 專欄執筆 / 大學教師

[email protected], http://www.jjhou.com

Page 2: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

講題提要 .Generics

自 JDK1.3 起, Generics 技術以各種外掛方式進入 Java 。 JDK1.5 正式內建此一技術,對 Java 及其 Library 帶來全面的影響與改寫。本講題追蹤該技術全面進入 JDK1.5 的狀況。

Generics

Page 3: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

講題提要 .Reflection

Reflection 為 Java 帶入靜態語言難以企及的動態應用,廣為人知者便是Component-based programming (例如 Javabean )開發環境 , deSerialization, 以及RMI ( Remote Method Invocation )。本講題說明 Reflection 基本觀念及 APIs 運用。

Reflection

Page 4: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

同質 (homogenous)容器與異質 (heterogenous) 容器同質容器:元素型別必須相同。C++ STL 的容器都是同質容器。list<int> myList;myList.push_back(3);

異質容器:元素型別可以不同。Java Collections 都是異質容器。LinkedList myList = new LinkedList();myList.add(new Double(4.4));myList.add(new String("jjhou"));

編譯器建立 int 版 -list

元素型別是 Object

Generics

Page 5: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

同質容器 in Java

Java 借鑑 C++ 語彙符號 "< >" ,建立同質容器,是謂 Generics in Java :

LinkedList<Integer> myList = new LinkedList<Integer>();myList.add(new Integer(4));myList.add(new Integer(7));myList.add(new String("hello")); //Error!

Generics

Page 6: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

同質容器與多型( Polymorphism )應用

Java Collections 原就充份運用多型:相當於 LinkedList

StrokeStroke RectRect CircleCircle

ObjectObject

22

11

33

44

66

55

77

LinkedList<Object> myList = new LinkedList<Object>();

18

2b

18

2c

5

18

2cStroke

Rect

Circlex:Integery:Integerr:Integer

x:Integery:Integerr:Integer

l:Integert:Integerw:Integerh:Integer

l:Integert:Integerw:Integerh:Integer

w:Integeria:ArrayList <Integer>

w:Integeria:ArrayList <Integer>

Generics

Page 7: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

同質容器與多型( Polymorphism )應用

為更好地運用多型,可這麼寫:

ShapeShape

ObjectObject

StrokeStroke RectRect CircleCircle

x:Integery:Integerr:Integer

x:Integery:Integerr:Integer

l:Integert:Integerw:Integerh:Integer

l:Integert:Integerw:Integerh:Integer

w:Integeria:ArrayList <Integer>

w:Integeria:ArrayList <Integer>

22

11

33

44

66

55

77

LinkedList<Shape> myList = new LinkedList<Shape>();

18

2b

18

2c

5

18

2cStroke

Rect

Circle

Generics

Page 8: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

加入 Generics 之前

Java 為保持語言的簡單性,強迫程式員在使用 Collections 時必須記住所擁有的元素型別;取出元素並進一步處理前,必須先轉型,從 Object 轉為實際型別。

LinkedList myList = new LinkedList();myList.add(new Integer(0));myList.add(new Integer(1));Integer tempi = (Integer)myList.iterator().next();

LinkedList myList = new LinkedList();myList.add(new Integer(0));myList.add(new Integer(1));Integer tempi = (Integer)myList.iterator().next();

Generics

Page 9: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

加入 Generics 之後

如果以 generic types 擴充 Java 語言,就能以更直接的方式表現 collection 的相關資訊,於是編譯器可追蹤記錄實際的元素型別,您也就不再需要轉型。有助於程式的開發與除錯。 LinkedList<Integer> iList = new LinkedList<Integer>();

iList.add(new Integer(0));iList.add(new Integer(1));Integer tempi = iList.iterator().next();

LinkedList<Integer> iList = new LinkedList<Integer>();iList.add(new Integer(0));iList.add(new Integer(1));Integer tempi = iList.iterator().next();

Generics

Page 10: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

Java/C++ 泛型技術的根本差異

template <typename T,...>class list { ... };template <typename T,...>class list { ... };

#include <list>list<int> li;list<string> ls;list<double> ld;

#include <list>list<int> li;list<string> ls;list<double> ld;

class list; // string 版本class list; // string 版本

list<int> li;list<string> ls;list<double> ld;

list<int> li;list<string> ls;list<double> ld;

class list; // int 版本class list; // int 版本

class list; // double 版本class list; // double 版本

public class LinkedList<E> { ... };public class LinkedList<E> { ... };

import java.util.*LinkedList<Integer> ...;LinkedList<String> ...;LinkedList<Double> ...;

import java.util.*LinkedList<Integer> ...;LinkedList<String> ...;LinkedList<Double> ...;

public class LinkedList { ... };public class LinkedList { ... };

import java.util.*LinkedList ...;LinkedList ...;LinkedList ...;

import java.util.*LinkedList ...;LinkedList ...;LinkedList ...;

list

java.util.LinkedList.java

.exe

.class

.class

膨脹法

擦拭法

C++

Java

Generics

Page 11: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

Generics Java 技術發展歷程

● JDK1.3 + GJ (a Generic Java language extension)以預處理器( %GJClasses%\gjc.Main ) + 翻新的Collections ( %GJClasses%\*.class )提供 GP 。● JDK1.4+JSR14 (Adding Generics to Java Language)以編譯器套件( %JSR14DISTR%\javac.jar) + 翻新的Collections ( %JSR14DISTR%\collect.jar)提供 GP 。● JDK1.5 內建所有必要的 GP 服務。 Java Library 全面翻新。

GJ 安裝後的路徑

JSR14 安裝後的路徑

Generics

Page 12: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

學習與觀察 Java Generics

● 運用 Generic Classes 例如 java.util (collections)● 運用 Generic Algorithms (methods) 例如 methods in java.util.Collection● 撰寫 Generic Classes● 撰寫 Generic Algorithms (methods)

Generics

Page 13: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

在 JDK1.5 中運用Generic Classes/Algorithms

ArrayList<String> strList = new ArrayList<String>();strList.add("zero");strList.add("one");strList.add("two");strList.add("five");System.out.println(strList); // [zero, one, two, five]String str = Collections.max(strList); Collections.sort(strList);

ArrayList<String> strList = new ArrayList<String>();strList.add("zero");strList.add("one");strList.add("two");strList.add("five");System.out.println(strList); // [zero, one, two, five]String str = Collections.max(strList); Collections.sort(strList);

static methods

Generics

Page 14: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

Boxing & UnBoxing 的影響

LinkedList<Integer> iList = new LinkedList<Integer>();iList.add(new Integer(0));iList.add(new Integer(1));iList.add(new Integer(5));iList.add(new Integer(2));

LinkedList<Integer> iList = new LinkedList<Integer>();iList.add(new Integer(0));iList.add(new Integer(1));iList.add(new Integer(5));iList.add(new Integer(2));

LinkedList<Integer> iList = new LinkedList<Integer>();iList.add(0); //boxingiList.add(1);iList.add(5);iList.add(2);int i = iList.get(2); //un-boxing

LinkedList<Integer> iList = new LinkedList<Integer>();iList.add(0); //boxingiList.add(1);iList.add(5);iList.add(2);int i = iList.get(2); //un-boxing

Generics

容器元素必須是 object (不可為純數值)

Page 15: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

觀摩 JDK1.5, java.util.Map

Generics

public interface Map<K,V> { V get(Object key); V put(K key, V value); V remove(Object key); void putAll(Map<? extends K, ? extends V> t); interface Entry<K,V> { … }...}

public interface Map<K,V> { V get(Object key); V put(K key, V value); V remove(Object key); void putAll(Map<? extends K, ? extends V> t); interface Entry<K,V> { … }...}

Page 16: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

觀摩 JDK1.4, java.util.Map

Generics

public interface Map { Object get(Object key); Object put(Object key, Object value); Object remove(Object key); void putAll(Map t); interface Entry { … }...}

public interface Map { Object get(Object key); Object put(Object key, Object value); Object remove(Object key); void putAll(Map t); interface Entry { … }...}

Page 17: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

觀摩 JDK1.5, java.util.ArrayList

Generics

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ private transient E[] elementData; private int size; public ArrayList(Collection<? extends E> c) { size = c.size(); // Allow 10% room for growth elementData = (E[])new Object[ (int)Math.min((size*110L)/100, Integer.MAX_VALUE)]; c.toArray(elementData); }...

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ private transient E[] elementData; private int size; public ArrayList(Collection<? extends E> c) { size = c.size(); // Allow 10% room for growth elementData = (E[])new Object[ (int)Math.min((size*110L)/100, Integer.MAX_VALUE)]; c.toArray(elementData); }...

Page 18: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

觀摩 JDK1.4, java.util.ArrayList

Generics

public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable{ private transient Object elementData[]; private int size; public ArrayList(Collection c) { size = c.size(); // Allow 10% room for growth elementData = new Object[ (int)Math.min((size*110L)/100, Integer.MAX_VALUE)]; c.toArray(elementData); }...

public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable{ private transient Object elementData[]; private int size; public ArrayList(Collection c) { size = c.size(); // Allow 10% room for growth elementData = new Object[ (int)Math.min((size*110L)/100, Integer.MAX_VALUE)]; c.toArray(elementData); }...

Page 19: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

在 JDK1.5 中撰寫 Generic Classes

ShapeShape

ObjectObject

StrokeStroke RectRect CircleCircle

x:T y:T r:T

x:T y:T r:T

l:T t:T w:T h:T

l:T t:T w:T h:T

w:T a:ArrayList<T> w:T a:ArrayList<T>

22

11

33

44

66

55

77

LinkedList<Shape> sList = new LinkedList<Shape>();

18

2b

18

2c

5

18

2cStroke<Integer,Integer>

Rect<Integer>

Circle<Integer>TTW,T

LinkedList<Shape> sList = new LinkedList<Shape>();sList.add(new Stroke<Integer,Integer>(…));sList.add(new Rect<Integer>(…));sList.add(new Circle<Integer>(…));

LinkedList<Shape> sList = new LinkedList<Shape>();sList.add(new Stroke<Integer,Integer>(…));sList.add(new Rect<Integer>(…));sList.add(new Circle<Integer>(…));

draw() len() compareTo()

draw() len() compareTo()

Generics

Page 20: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

在 JDK1.5 中撰寫 Generic Classes

public abstract class Shape implements Comparable<Shape>{ public abstract void draw(); public abstract double len(); public int compareTo(Shape o) { return (this.len() < o.len() ? -1 : (this.len() == o.len() ? 0 : 1)); }}

public abstract class Shape implements Comparable<Shape>{ public abstract void draw(); public abstract double len(); public int compareTo(Shape o) { return (this.len() < o.len() ? -1 : (this.len() == o.len() ? 0 : 1)); }}

public class Stroke<W,T> extends Shape implements Serializable { W width; ArrayList<T> a; public double len() { ... } public void draw() { ... }}

public class Stroke<W,T> extends Shape implements Serializable { W width; ArrayList<T> a; public double len() { ... } public void draw() { ... }}

典型的 Template Method

為了可用於 max()

實際計算長度時,恐怕會遭遇麻煩 !

只要 class 名稱加上 <>即成為 generic class

Generics

類似設計是 public final class Integer extends Number implements Comparable<Integer>

Page 21: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

在 JDK1.5 中撰寫 Generic Classespublic class Rect<T> extends Shape implements Serializable { T l,t,w,h; public void draw() { ... } public double len() { ... }}

public class Rect<T> extends Shape implements Serializable { T l,t,w,h; public void draw() { ... } public double len() { ... }} public class Circle<T>

extends Shape implements Serializable { T x,y,r; public double len() { ... } public void draw() { ... }}

public class Circle<T> extends Shape implements Serializable { T x,y,r; public double len() { ... } public void draw() { ... }}

實際計算長度時,恐怕會遭遇麻煩 !

只要 class 名稱之後加上 <> ,即成為 generic class

Generics

類似的設計是 Class<T>

Page 22: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

在 JDK1.5 中撰寫 Generic Algorithms

// in someone classpublic static <T> T gMethod (List<T> list) { ... }

// in someone classpublic static <T> T gMethod (List<T> list) { ... }

public static <T extends Comparable<T>> T gMethod (List<T> list) { ... }public static <T extends Comparable<T>> T gMethod (List<T> list) { ... }

public static List<?> gMethod (List<?> list){ return list; // (本例)原封不動地傳回}

public static List<?> gMethod (List<?> list){ return list; // (本例)原封不動地傳回}

只要 method 名稱之前加上 <> ,即成為 generic method

"bounded type parameter"" 受到更多約束 " 的型別參數

JDK 1.5 允許「不被 method 真正用到」的型別參數以符號 '?' 表示

Generics

形式 (1)

形式 (2)

形式 (3)

Page 23: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

觀摩 JDK1.4, java.util.Collections.max()

#001 public class Collections { #002 ...#003 public static #004 //這裡刻意空一行,以利與 JDK1.5源碼比較#005 Object max(Collection coll) {#006 Iterator i = coll.iterator();#007 Comparable candidate = (Comparable)(i.next());#008 #009 while(i.hasNext()) {#010 Comparable next = (Comparable)(i.next());#011 if (next.compareTo(candidate) > 0)#012 candidate = next;#013 }#014 return candidate;#015 }#016 ...#017 } // of Collections

#001 public class Collections { #002 ...#003 public static #004 //這裡刻意空一行,以利與 JDK1.5源碼比較#005 Object max(Collection coll) {#006 Iterator i = coll.iterator();#007 Comparable candidate = (Comparable)(i.next());#008 #009 while(i.hasNext()) {#010 Comparable next = (Comparable)(i.next());#011 if (next.compareTo(candidate) > 0)#012 candidate = next;#013 }#014 return candidate;#015 }#016 ...#017 } // of Collections

Generics

Page 24: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

觀摩 JDK1.5, java.util.Collections.max()

#001 public class Collections { #002 ...#003 public static #004 <T extends Object & Comparable<? super T>> #005 T max(Collection<? extends T> coll) {#006 Iterator<? extends T> i = coll.iterator();#007 T candidate = i.next();#008 #009 while(i.hasNext()) {#010 T next = i.next();#011 if (next.compareTo(candidate) > 0)#012 candidate = next;#013 }#014 return candidate;#015 }#016 ...#017 } // of Collections

#001 public class Collections { #002 ...#003 public static #004 <T extends Object & Comparable<? super T>> #005 T max(Collection<? extends T> coll) {#006 Iterator<? extends T> i = coll.iterator();#007 T candidate = i.next();#008 #009 while(i.hasNext()) {#010 T next = i.next();#011 if (next.compareTo(candidate) > 0)#012 candidate = next;#013 }#014 return candidate;#015 }#016 ...#017 } // of Collections

Generics

Page 25: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

觀摩 JDK1.5, java.util.Collections.max()

1 2

3 4 5

6

1. max() 將接收一個 Collection object

2. 該 Collection object 所含元素必須是 T-derived object

3. T 必須繼承自 Object (這倒不必明說。 Java 必定如此)4. T 必須實作 Comparable

5. Comparable 所比較的型別必須是 supertype of T

6. max() 傳回 T object

Generics

Page 26: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

所謂 Introspection ( 內省 , 內觀 , 反省 )

Reflection

看透( "look inside" ) classes 的能力,我們稱之為 introspection 。或說 "the ability of the program to examine itself"

Java 有兩個作法可以進行 introspection :(1) Static Introspection : .class file inspection (2) Dynamic Introspection : Reflection API

Page 27: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

所謂 Reflection

Reflection

Reflection 是 Java 被視為動態(或準動態)語言的關鍵,允許程式於執行期透過 Reflection APIs 取得任何已知名稱之 class 的內部資訊,包括 package 、 type parameters 、 superclass 、 implemented interfaces 、 inner classes, outer class, fields 、 constructors 、 methods 、 modifiers ,並可於執行期生成 instances 、變更 fields 內容或喚起 methods 。

Page 28: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

所謂 Reflection

Reflection

Test.classTest.class

disk

Test class definition(Class object for Test class)

Test class definition(Class object for Test class)

dynamic loadingby class loader (a ClassLoader object)

virtual machine environment對於每一個 class , JRE 都會維護一個對應的不可改動的( immutable ) Class object ,其中內含該 class 資訊 . Reflection APIs 便是從中取得資訊

Page 29: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

Reflection APIs

Reflection

有了 Reflection API ,我們可以: •決定(判斷)某個 object 所屬的 class. •取得 class 的 modifiers, fields, methods, constructors, 和 superclasses 的相關資訊 . •找出 interface 中的 constants 和 method declarations. •為一個執行期才得知名稱的 class 產生實體(物件) .•取得及設定 object's field 值 , 即使執行前對它一無所知 . •喚起( invoke ) object' method ,即使執行期才得知它 . •產生一個新的 array, 其大小和元素型別 (component type)

在執行之前未知。並可更動 array 的元素 .

Page 30: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

Reflection APIs

Reflection

Core Reflection API 容納兩類應用。第一類應用需要找出並使用某個 object 的 run-time class 的所有 public members 。這些應用要求能夠於執行期存取 該 object 的所有 public fields, methods, constructors 。例如 Java Beans 提供的 services ,以及 lightweight tools 如 object inspectors 。這些應用程式統是使用 Class 所提供的 methods: getField, getMethod, getConstructor, getFields, getMethods, getConstructors 來獲得 classes Field, Method, Constructor 的 instances 。

第二類應用很精巧,需要找出並使用被某個 class 宣告的 members 。它們需要能夠於執行期存取「由 class file 供應之 class 實作層級」。例如 development tools 如 interpreters, inspectors, 以及 class browsers, 以及 run-time services 如 Java Object Serialization 。這些應用使用 Class 所提供的 methods: getDeclaredField, getDeclaredMethod, getDeclaredConstructor, getDeclaredFields, getDeclaredMethods, getDeclaredConstructors 來獲得 classes Field, Method, Constructor 的 instances 。

Page 31: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

Reflection APIs

Reflection

Reflection API 由 java.lang.Class 和 java.lang.reflect classes: (1)Field, (2)Method, (3)Constructor, (4)Array, (5)Modifier 組成。

前三者表現 classes / interfaces 的相應

(corresponding) 成員。 Array 提供 methods 用來建立 , 存取 , 改動 arrays 。 Modifier 提供 methods 對 modifiers ( 如 static, public) 解碼(解釋)。

Page 32: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

Object class

Reflection

public class Object { public final native Class<? extends Object> getClass(); public native int hashCode(); public boolean equals(Object obj) {

return (this == obj); } protected native Object clone() throws CloneNotSupportedException; public String toString() {

return getClass().getName() + "@" + Integer.toHexString(hashCode()); } public final native void notify(); public final native void notifyAll(); public final native void wait(long timeout) throws InterruptedException; public final void wait(long timeout, int nanos) throws InterruptedException; public final void wait() throws InterruptedException; protected void finalize() throws Throwable { }}

public class Object { public final native Class<? extends Object> getClass(); public native int hashCode(); public boolean equals(Object obj) {

return (this == obj); } protected native Object clone() throws CloneNotSupportedException; public String toString() {

return getClass().getName() + "@" + Integer.toHexString(hashCode()); } public final native void notify(); public final native void notifyAll(); public final native void wait(long timeout) throws InterruptedException; public final void wait(long timeout, int nanos) throws InterruptedException; public final void wait() throws InterruptedException; protected void finalize() throws Throwable { }}

Object class 是所有 Java classes 的 root 。

java.lang.Object

java.lang.Class

Page 33: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

Class class

Reflection

Class instance 所表現的,是執行中的 Java 程式內的 classes 和 interfaces 。 enum, annotation, array, primitive Java types (boolean, byte, char, short, int, long, float, double), 以及關鍵字 void 也都可被表現為 Class objects. Class 並沒有 public constructor ,其 objects 係當 classes 被載入或 class loader 的 defineClass() 被呼叫時,由 Java Virtual Machine 自動建構。 以下使用 Class object 列印某個 object 的 class 名稱:void printClassName(Object obj) { System.out.println("The class of " + obj + " is " + obj.getClass().getName());} 也可對已知型別(或 void ),根據其 class literal 取得 Class object ,例如:System.out.println("The name of class Foo is: "+Foo.class.getName());

Class instance 所表現的,是執行中的 Java 程式內的 classes 和 interfaces 。 enum, annotation, array, primitive Java types (boolean, byte, char, short, int, long, float, double), 以及關鍵字 void 也都可被表現為 Class objects. Class 並沒有 public constructor ,其 objects 係當 classes 被載入或 class loader 的 defineClass() 被呼叫時,由 Java Virtual Machine 自動建構。 以下使用 Class object 列印某個 object 的 class 名稱:void printClassName(Object obj) { System.out.println("The class of " + obj + " is " + obj.getClass().getName());} 也可對已知型別(或 void ),根據其 class literal 取得 Class object ,例如:System.out.println("The name of class Foo is: "+Foo.class.getName());

java.lang.Object

java.lang.Class

Page 34: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

Class class

Reflection

public String toString() { return ( isInterface() ? "interface " : (isPrimitive() ? "" : "class ")) + getName(); }

public String toString() { return ( isInterface() ? "interface " : (isPrimitive() ? "" : "class ")) + getName(); }

public final class Class<T> implements java.io.Serializable,

java.lang.reflect.GenericDeclaration, java.lang.reflect.Type,

java.lang.reflect.AnnotatedElement { private Class() {}

public final class Class<T> implements java.io.Serializable,

java.lang.reflect.GenericDeclaration, java.lang.reflect.Type,

java.lang.reflect.AnnotatedElement { private Class() {}

Class 並沒有 public constructor 。其 objects 係當 classes 被載入 ( loadClass(...) )或 class loader 的 defineClass(...) 被呼叫時,由 Java Virtual Machine 自動建構。因此,我可以(修改源碼後)測得某個 class 被載入,卻無法測得其對應之 Class object 的誕生。

...

Page 35: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

Class class

Reflection

From getClass(). String str = "abc"; Class c1 = str.getClass(); From the method Class.getSuperclass() Button b = new Button(); Class c1 = b.getClass(); Class c2 = c1.getSuperclass();BTW getSuperclass() returns null for the class Object.

From the static method Class.forName() Class c1 = Class.forName ("java.lang.String"); Class c2 = Class.forName ("java.awt.Button"); Class c3 = Class.forName ("java.util.LinkedList$Entry"); Class c4 = Class.forName ("I"); Class c5 = Class.forName ("[I");

From getClass(). String str = "abc"; Class c1 = str.getClass(); From the method Class.getSuperclass() Button b = new Button(); Class c1 = b.getClass(); Class c2 = c1.getSuperclass();BTW getSuperclass() returns null for the class Object.

From the static method Class.forName() Class c1 = Class.forName ("java.lang.String"); Class c2 = Class.forName ("java.awt.Button"); Class c3 = Class.forName ("java.util.LinkedList$Entry"); Class c4 = Class.forName ("I"); Class c5 = Class.forName ("[I");

From the .class syntax Class c1 = String.class; Class c2 = java.awt.Button.class; Class c3 = Main.InnerClass.class; Class c4 = int.class; Class c5 = int[].class; From the primitive wrapper classes Class c1 = Boolean.TYPE; Class c2 = Byte.TYPE; Class c3 = Character.TYPE; Class c4 = Short.TYPE; Class c5 = Integer.TYPE; Class c6 = Long.TYPE; Class c7 = Float.TYPE; Class c8 = Double.TYPE; Class c9 = Void.TYPE;

From the .class syntax Class c1 = String.class; Class c2 = java.awt.Button.class; Class c3 = Main.InnerClass.class; Class c4 = int.class; Class c5 = int[].class; From the primitive wrapper classes Class c1 = Boolean.TYPE; Class c2 = Byte.TYPE; Class c3 = Character.TYPE; Class c4 = Short.TYPE; Class c5 = Integer.TYPE; Class c6 = Long.TYPE; Class c7 = Float.TYPE; Class c8 = Double.TYPE; Class c9 = Void.TYPE;

獲得 java.lang.Class objects 的各種辦法

Page 36: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

ClassLoader class

Reflection

所謂 class loader 是個 object ,負責載入 classes 。 ClassLoader 是個 abstract class 。給予它 class 名稱, class loader 便應該嘗試定位 (locate) 或生成 (generate) 某些資料,用以構成一個 class definition 。典型策略是將該名稱轉換為檔名,然後讀入對應的 "class file" 。 每個 Class object 都內含一個 getClassLoader(), reference to 「定義該 Class object 」的那個 ClassLoader 。

ClassLoader class 運用 delegation model 來搜尋 classes 和 resources 。其每一個 instance 都有一個 associated parent class loader 。一旦請求搜尋一個 class 或 resource , ClassLoader instance 便會將工作委託 (delegate) 給其 parent class loader ,在企圖找到 class 或 resource 本身之前。 Virtual machine 的內建 class loader 稱為 bootstrap class loader ,它本身沒有 parent ,但也許用做一個 ClassLoader instance 的 parent 。

通常, Java virtual machine 以一種 platform-dependent 方式從 local file system 載入 classes 。例如在 UNIX 系統上, virtual machine 從環境變數 CLASSPATH 所定義的目錄中載入 classes 。 然而某些 classes 最初或許並非來自檔案,而是來自其他資源,像是網絡,或是被應用程式所建構。 method defineClass(String, byte[], int, int) 會轉換 an array of bytes 成為一個 Class instance 。這種新定義出來的 class ,可使用 Class.newInstance() 產生 instances 。

所謂 class loader 是個 object ,負責載入 classes 。 ClassLoader 是個 abstract class 。給予它 class 名稱, class loader 便應該嘗試定位 (locate) 或生成 (generate) 某些資料,用以構成一個 class definition 。典型策略是將該名稱轉換為檔名,然後讀入對應的 "class file" 。 每個 Class object 都內含一個 getClassLoader(), reference to 「定義該 Class object 」的那個 ClassLoader 。

ClassLoader class 運用 delegation model 來搜尋 classes 和 resources 。其每一個 instance 都有一個 associated parent class loader 。一旦請求搜尋一個 class 或 resource , ClassLoader instance 便會將工作委託 (delegate) 給其 parent class loader ,在企圖找到 class 或 resource 本身之前。 Virtual machine 的內建 class loader 稱為 bootstrap class loader ,它本身沒有 parent ,但也許用做一個 ClassLoader instance 的 parent 。

通常, Java virtual machine 以一種 platform-dependent 方式從 local file system 載入 classes 。例如在 UNIX 系統上, virtual machine 從環境變數 CLASSPATH 所定義的目錄中載入 classes 。 然而某些 classes 最初或許並非來自檔案,而是來自其他資源,像是網絡,或是被應用程式所建構。 method defineClass(String, byte[], int, int) 會轉換 an array of bytes 成為一個 Class instance 。這種新定義出來的 class ,可使用 Class.newInstance() 產生 instances 。

Page 37: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

Class 涵蓋範圍 ( 局部 ) Package getPackage()

String getName()

TypeVariable<Class>[]getTypeParameters()

Class getSuperClass()Class[] getInterfaces()

Class[] getDeclaredClasses()Class getDeclaringClass()

Consructor[] getDeclaredConstructors()

Method[]getDeclaredMethods()

Field[]getDeclaredFields()

but 無法取得 import lib...

Package getPackage()

String getName()

TypeVariable<Class>[]getTypeParameters()

Class getSuperClass()Class[] getInterfaces()

Class[] getDeclaredClasses()Class getDeclaringClass()

Consructor[] getDeclaredConstructors()

Method[]getDeclaredMethods()

Field[]getDeclaredFields()

but 無法取得 import lib...

package java.util;public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Queue<E>, Cloneable, java.io.Serializable{ private static class Entry<E> { … }

public LinkedList() { … } public LinkedList(Collection<? extends E> c) { … }

public E getFirst() { … } public E getLast() { … }

private transient Entry<E> header = …; private transient int size = 0;}

Reflection

Class methods

1

2

3

4

5

7

8

9

6

Page 38: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

小工具 tName()

Reflection

static String tName(String nm, Hashtable ht) { String yy; String arr;

if (nm.charAt(0) != '[') { int i = nm.lastIndexOf("."); if (i == -1) return nm; // primitive type, ignore it. else { yy = nm.substring(i+1); if (ht != null) ht.put(nm, yy); return yy; } } ...

static String tName(String nm, Hashtable ht) { String yy; String arr;

if (nm.charAt(0) != '[') { int i = nm.lastIndexOf("."); if (i == -1) return nm; // primitive type, ignore it. else { yy = nm.substring(i+1); if (ht != null) ht.put(nm, yy); return yy; } } ...

java.lang.Integer

lastIndexOf(".")

yy (class name part)nm (fully qualified name)

Integer java.lang.Integer

key value

這樣是一個 Hashtable 元素

Page 39: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 package

Package getPackage()Package getPackage()

package java.util;

Class c = null;c = Class.forName(args[0]);

Package p;p = c.getPackage();

if (p != null) System.out.println("package "+p.getName()+";");

Class c = null;c = Class.forName(args[0]);

Package p;p = c.getPackage();

if (p != null) System.out.println("package "+p.getName()+";");

Reflection

1

package java.util;

Page 40: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得完整的 import list

Reflection

ff = c.getDeclaredFields();for (int i = 0; i < ff.length; i++) x = tName(ff[i].getType().getName(), classRef);cn = c.getDeclaredConstructors();for (int i = 0; i < cn.length; i++) { Class cx[] = cn[i].getParameterTypes(); for (int j = 0; j < cx.length; j++) x = tName(cx[j].getName(), classRef);}mm = c.getDeclaredMethods();for (int i = 0; i < mm.length; i++) { x = tName(mm[i].getReturnType().getName(), classRef); Class cx[] = mm[i].getParameterTypes(); for (int j = 0; j < cx.length; j++) x = tName(cx[j].getName(), classRef);}classRef.remove(c.getName());

(1) 取得所有 fields ,將其 type記錄於 hashtable

(2) 取得所有 ctors ,將其 parameters type記錄於 hashtable

(3) 取得所有 methods ,將其 return/parameters type記錄於 hashtable

(4) 從 hashtable 中移除自己

Constructor cn[];Method mm[];Field ff[];

Page 41: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得完整的 import list

Reflection

import java.lang.Object;import java.util.Collection;import java.util.Set;

import java.util.ListIterator;import java.lang.Object;import java.util.LinkedList$Entry;import java.util.Collection;import java.io.ObjectOutputStream;import java.io.ObjectInputStream;

Page 42: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 class name 及 modifier

String getName()String getName()

public class LinkedList<E>

Reflection

2

c = Class.forName(args[0]);int mod = c.getModifiers();System.out.print(Modifier.toString(mod)); //整個 modifier

if (Modifier.isInterface(mod)) System.out.print(" "); //"interface" 已含於 modifierelse System.out.print(" class "); // 關鍵字 "class"System.out.print(tName(c.getName(), null)); //class 名稱

c = Class.forName(args[0]);int mod = c.getModifiers();System.out.print(Modifier.toString(mod)); //整個 modifier

if (Modifier.isInterface(mod)) System.out.print(" "); //"interface" 已含於 modifierelse System.out.print(" class "); // 關鍵字 "class"System.out.print(tName(c.getName(), null)); //class 名稱

public class LinkedList

public final class Class

public abstract interface Map

Page 43: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 Type Parameters

TypeVariable<Class>[]getTypeParameters()TypeVariable<Class>[]getTypeParameters()

package java.utilpublic class LinkedList<E>

Reflection

TypeVariable<Class>[] tv;tv = c.getTypeParameters(); //warning: unchecked conversionfor (int i = 0; i < tv.length; i++) { x = tName(tv[i].getName(), null); // 例如 E,K,V... if (i == 0) // 第一個 System.out.print("<" + x); else //非第一個 System.out.print("," + x); if (i == tv.length-1) //最後一個 System.out.println(">"); }

TypeVariable<Class>[] tv;tv = c.getTypeParameters(); //warning: unchecked conversionfor (int i = 0; i < tv.length; i++) { x = tName(tv[i].getName(), null); // 例如 E,K,V... if (i == 0) // 第一個 System.out.print("<" + x); else //非第一個 System.out.print("," + x); if (i == tv.length-1) //最後一個 System.out.println(">"); }

public class LinkedList<E>

public abstract interface Map<K,V>

3

Page 44: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 Super ClassClass getSuperClass()Class getSuperClass()

public class LinkedList<E> extends AbstractSequentialList<E>

Reflection

Class supClass;supClass = c.getSuperclass();if (supClass != null) // 如果有 super class System.out.print(" extends" + tName(supClass.getName(),classRef));

Class supClass;supClass = c.getSuperclass();if (supClass != null) // 如果有 super class System.out.print(" extends" + tName(supClass.getName(),classRef));

public class LinkedList<E> extends AbstractSequentialList, implements List, Queue, Cloneable, Serializable, {

4

Page 45: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 Implemented InterfacesClass[] getInterfaces()Class[] getInterfaces()public class LinkedList<E>

extends AbstractSequentialList<E> implements List<E>, Queue<E>, Cloneable, java.io.Serializable

Reflection

Class cc[];Class ctmp; // 找出所有被實現的 interfacescc = c.getInterfaces(); if (cc.length != 0) System.out.print(", \r\n" + " implements ");for (Class cite : cc) System.out.print(tName(cite.getName(), null)+", ");

Class cc[];Class ctmp; // 找出所有被實現的 interfacescc = c.getInterfaces(); if (cc.length != 0) System.out.print(", \r\n" + " implements ");for (Class cite : cc) System.out.print(tName(cite.getName(), null)+", ");

5

public class LinkedList<E> extends AbstractSequentialList, implements List, Queue, Cloneable, Serializable, {

JDK1.5, for loop 新語法

Page 46: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 DeclaredClasses (inner classes)和 DeclaringClass (outer class)Class[] getDeclaredClasses()

Class getDeclaringClass()Class[] getDeclaredClasses()Class getDeclaringClass()public class LinkedList<E> ...

{ private static class Entry<E> { … } class name: LinkedList$Entry

Reflection

6

cc = c.getDeclaredClasses(); // 找出 inner classesfor (Class cite : cc) System.out.println(tName(cite.getName(), null));

ctmp = c.getDeclaringClass(); // 找出 outer classesif (ctmp != null) System.out.println(ctmp.getName());

cc = c.getDeclaredClasses(); // 找出 inner classesfor (Class cite : cc) System.out.println(tName(cite.getName(), null));

ctmp = c.getDeclaringClass(); // 找出 outer classesif (ctmp != null) System.out.println(ctmp.getName());

LinkedList$EntryLinkedList$ListItr Map$Entry

Page 47: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 Declared Constructors (1)

Consructor[] getDeclaredConstructors()Consructor[] getDeclaredConstructors()

public class LinkedList<E> ...{ public LinkedList() { … } public LinkedList(Collection<? extends E> c) { … }

Reflection

7

Page 48: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 Declared Constructors (2)

Reflection

Constructor cn[];cn = c.getDeclaredConstructors();for (int i = 0; i < cn.length; i++) { int md = cn[i].getModifiers(); System.out.print(" " + Modifier.toString(md) + " " + cn[i].getName()); Class cx[] = cn[i].getParameterTypes(); System.out.print("("); for (int j = 0; j < cx.length; j++) { System.out.print(tName(cx[j].getName(), null)); if (j < (cx.length - 1)) System.out.print(", "); } System.out.print(")"); System.out.println("G: " + cn[i].toGenericString());}

Constructor cn[];cn = c.getDeclaredConstructors();for (int i = 0; i < cn.length; i++) { int md = cn[i].getModifiers(); System.out.print(" " + Modifier.toString(md) + " " + cn[i].getName()); Class cx[] = cn[i].getParameterTypes(); System.out.print("("); for (int j = 0; j < cx.length; j++) { System.out.print(tName(cx[j].getName(), null)); if (j < (cx.length - 1)) System.out.print(", "); } System.out.print(")"); System.out.println("G: " + cn[i].toGenericString());}

public java.util.LinkedList(Collection) G: public java.util.LinkedList(java.util.Collection<? extends E>) public java.util.LinkedList() G: public java.util.LinkedList()

Page 49: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 Declared Methods (1)

Method[]getDeclaredMethods()Method[]getDeclaredMethods()

public class LinkedList<E> ...{ public E getFirst() { … } public E getLast() { … }

Reflection

8

Page 50: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 Declared Methods (2)

Reflection

Method mm[];mm = c.getDeclaredMethods();for (int i = 0; i < mm.length; i++) { int md = mm[i].getModifiers(); System.out.print(" "+Modifier.toString(md)+" "+ tName(mm[i].getReturnType().getName(), null)+" "+ mm[i].getName()); Class cx[] = mm[i].getParameterTypes(); System.out.print("("); for (int j = 0; j < cx.length; j++) { System.out.print(tName(cx[j].getName(), null)); if (j < (cx.length - 1)) System.out.print(", "); } System.out.print(")"); System.out.println("G: " + mm[i].toGenericString());}

Method mm[];mm = c.getDeclaredMethods();for (int i = 0; i < mm.length; i++) { int md = mm[i].getModifiers(); System.out.print(" "+Modifier.toString(md)+" "+ tName(mm[i].getReturnType().getName(), null)+" "+ mm[i].getName()); Class cx[] = mm[i].getParameterTypes(); System.out.print("("); for (int j = 0; j < cx.length; j++) { System.out.print(tName(cx[j].getName(), null)); if (j < (cx.length - 1)) System.out.print(", "); } System.out.print(")"); System.out.println("G: " + mm[i].toGenericString());}

public Object get(int) G: public E java.util.LinkedList.get(int) public int size() G: public int java.util.LinkedList.size()

Page 51: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 Declared Fields (1)

Field[]getDeclaredFields()Field[]getDeclaredFields()

public class LinkedList<E> ...{ private transient Entry<E> header = …; private transient int size = 0;}

Reflection

9

Page 52: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 Declared Fields (2)

Reflection

Field ff[];ff = c.getDeclaredFields();for (int i = 0; i < ff.length; i++) { int md = ff[i].getModifiers(); System.out.println(" "+Modifier.toString(md)+" "+ tName(ff[i].getType().getName(), null) +" "+ ff[i].getName()+";"); System.out.println("G: " + ff[i].toGenericString()); }

Field ff[];ff = c.getDeclaredFields();for (int i = 0; i < ff.length; i++) { int md = ff[i].getModifiers(); System.out.println(" "+Modifier.toString(md)+" "+ tName(ff[i].getType().getName(), null) +" "+ ff[i].getName()+";"); System.out.println("G: " + ff[i].toGenericString()); }

private transient LinkedList$Entry header;G: private transient java.util.LinkedList.java.util.LinkedList$Entry<E> java.util.LinkedList.header private transient int size;G: private transient int java.util.LinkedList.size

Page 53: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

動態生成 object(class name 於執行期才得知 )

Reflection

1. 建構時 no argument

2. 建構時 with arguments

Class c = Class.forName("DynTest");Object obj = null;obj = c.newInstance(); // 不帶引數System.out.println(obj);

Class c = Class.forName("DynTest");Object obj = null;obj = c.newInstance(); // 不帶引數System.out.println(obj);

Class c = Class.forName("DynTest");Class[] pTypes = new Class[] { double.class, int.class };Constructor ctor = c.getConstructor(pTypes); //指定 parameter list ,便可獲得特定之 ctor Object obj = null;Object[] arg = new Object[] {3.14159, 125}; //引數obj = ctor.newInstance(arg);System.out.println(obj);

Class c = Class.forName("DynTest");Class[] pTypes = new Class[] { double.class, int.class };Constructor ctor = c.getConstructor(pTypes); //指定 parameter list ,便可獲得特定之 ctor Object obj = null;Object[] arg = new Object[] {3.14159, 125}; //引數obj = ctor.newInstance(arg);System.out.println(obj);

Page 54: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 /設定 object's fields 內容(field's name 於執行期才得知 )

Reflection

1. 首先產生 "field 所屬 class" 的一個 Class object c 。2. 呼叫 c.getField(_) 製造出一個 Field object f 。必須餵以 field name 。 3. 視需要呼叫 (Type)f.get(obj) 或 f.set(obj, newValue) 。呼叫時必須餵以 calling obj (和 newValue )。

Page 55: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

取得 /設定 object's fields 內容(field's name 於執行期才得知 )

Reflection

public class Test { public double d; public static void main(String args[]) { Class c = Class.forName("Test"); Field f = c.getField("d"); Test obj = new Test(); System.out.println("d= " + (Double)f.get(obj)); f.set(obj, 12.34); System.out.println("d= " + obj.d); }}

public class Test { public double d; public static void main(String args[]) { Class c = Class.forName("Test"); Field f = c.getField("d"); Test obj = new Test(); System.out.println("d= " + (Double)f.get(obj)); f.set(obj, 12.34); System.out.println("d= " + obj.d); }}

Test.class

1

2

3

Page 56: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

喚起 object's methods(method's name 於執行期才得知 )

1. 首先產生 "method 所屬 class" 的一個 Class object c 。2. 呼叫 c.getMethod(_,_) 製造出一個 Method object m 。必須餵以 signature (method name & parameters list) 。 3. 呼叫 m.invoke(_,_) ,必須餵以一個 calling object 和一個 arguments list.

Page 57: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

知道 signature就可做出 Method object

喚起 object's methods ( 例 1)

public int add(int a, int b){ return a + b;}public static void main(String args[]){ Class c = Class.forName("Test"); Class ptypes[] = new Class[2]; ptypes[0] = Integer.TYPE; ptypes[1] = Integer.TYPE; Method m = c.getMethod("add",ptypes); Test obj = new Test(); Object args[] = new Object[2]; arg[0] = new Integer(37); arg[1] = new Integer(47); Object r = m.invoke(obj, arg); Integer rval = (Integer)r; System.out.println(rval.intValue());}

public int add(int a, int b){ return a + b;}public static void main(String args[]){ Class c = Class.forName("Test"); Class ptypes[] = new Class[2]; ptypes[0] = Integer.TYPE; ptypes[1] = Integer.TYPE; Method m = c.getMethod("add",ptypes); Test obj = new Test(); Object args[] = new Object[2]; arg[0] = new Integer(37); arg[1] = new Integer(47); Object r = m.invoke(obj, arg); Integer rval = (Integer)r; System.out.println(rval.intValue());}

Test obj = new Test();obj.add(37, 47)

add(int a, int b)

呼叫 Method::invoke(x,x) ,給予 calling object 和 argument list. (Object[ ]) ,獲得 Object.

Test.class

1

2

3

Page 58: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

知道 signature就可做出 Method object

喚起 object's methods ( 例 2)

public String func(String s, Hashtable ht){ System.out.println("func invoked"); return s; }public static void main(String args[]){ Class c = Class.forName("Test"); Class ptypes[] = new Class[2]; ptypes[0] = Class.forName("java.lang.String"); ptypes[1] = Class.forName("java.util.Hashtable"); Method m = c.getMethod("func",ptypes); Test obj = new Test(); Object args[] = new Object[2]; arg[0] = new String("Hello,world"); arg[1] = null; Object r = m.invoke(obj, arg); Integer rval = (String)r; System.out.println(rval);}

public String func(String s, Hashtable ht){ System.out.println("func invoked"); return s; }public static void main(String args[]){ Class c = Class.forName("Test"); Class ptypes[] = new Class[2]; ptypes[0] = Class.forName("java.lang.String"); ptypes[1] = Class.forName("java.util.Hashtable"); Method m = c.getMethod("func",ptypes); Test obj = new Test(); Object args[] = new Object[2]; arg[0] = new String("Hello,world"); arg[1] = null; Object r = m.invoke(obj, arg); Integer rval = (String)r; System.out.println(rval);}

Test obj = new Test();obj.tName("Hello", null)

tName(String s, Hashtable ht)

呼叫 Method::invoke(x,x) ,給予 calling object 和 argument list. (Object[ ]) ,獲得 Object.

Test.class

1

2

3

Page 59: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

本例使用之 Reflection APIsforNamegetNamegetDeclaredFieldsgetDeclaredMethodsgetDeclaredConstructorsgetDeclaredClassesgetDeclaringClassgetModifiersgetSuperClassgetGenericInterfacesgetGenericSuperclassgetInterfacesgetPackageisArrayisEnumisPrimitiveisSyntheticisAnnotation isInterfacegetTypeParametersnewInstance

forNamegetNamegetDeclaredFieldsgetDeclaredMethodsgetDeclaredConstructorsgetDeclaredClassesgetDeclaringClassgetModifiersgetSuperClassgetGenericInterfacesgetGenericSuperclassgetInterfacesgetPackageisArrayisEnumisPrimitiveisSyntheticisAnnotation isInterfacegetTypeParametersnewInstance

Class class:

getNamegetParameterTypesgetModifierstoGenericString

getNamegetParameterTypesgetModifierstoGenericString

Constructor class:

getNamegetParameterTypesgetReturnTypegetModifiers toGenericStringinvoke

getNamegetParameterTypesgetReturnTypegetModifiers toGenericStringinvoke

Method class:

getNamegetTypegetModifiersgetxxxsetxxxtoGenericString

getNamegetTypegetModifiersgetxxxsetxxxtoGenericString

Field class:

IsInterfaceIsxxxtoString

IsInterfaceIsxxxtoString

Modifier class:

[empty][empty]

Type class:

getName getName

Package class:

getNamegetGenericDeclaration getNamegetGenericDeclaration

TypeVariable class:

Page 60: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

Java Library 源碼修改經驗

c:\jdk150\src\java\lang\Class.java ↑待改源碼(備份為宜)。修改後編譯獲得 *.class 。c:\jdk150\jre\lib\rt.jar ↑Java Library classes (過程中不受影響)c:\somewhere\Test.java ↑測試程式c:\jdk150\jre\lib\endorsed ↑新增目錄, classloader 將優先從這兒讀取 .jar 。將 *.class搬移到 e:\java\lang ,壓縮為 foo.zip (任意命名。需夾帶路徑java\lang ),再將 foo.zip搬至 endorsed目錄並改名為foo.jar ,於是測試程式便可正確用到修改後的 classes

Page 61: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

Java Library 源碼修改經驗

把修改後的 .java 編譯為 .class ,壓縮為 xxx.jar (需帶路徑 java\lang )並搬移到 endorsed ,即可被 class loader優先讀取。

myclass.jar

Page 62: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會

更多資訊"Java泛型技術之發展 "http://www.jjhou.com/javatwo-2002.htm

本講題三個範例程式http://www.jjhou.com/javatwo-2004-reflection-and-generics-in-jdk15-sample.zip

《 Java Reflection in Action 》 , by Ira R. Forman and Nate FormanManning Publications Co. http://www.manning.com/catalog/view.php?book=forman

"Take an in-depth look at the Java Reflection API" -- Learn about the new Java 1.1 tools for finding out information about classeshttp://www.javaworld.com/javaworld/jw-09-1997/jw-09-indepth.html

"Take a look inside Java classes" -- Learn to deduce properties of a Java class from inside a Java programhttp://www.javaworld.com/javaworld/jw-08-1997/jw-08-indepth.html

Page 63: Reflection & Generics in JDK1.5

2004 Java2 專業技術大會