反射的相關概念
1.清除封裝-將域設置成私有的,而後提供相對應的set和get方法來操做這個域。可是咱們能夠經過Java的反射機制來修改類的私有域。
主要技術:
Field類提供有關類或接口的單個字段的信息,以及它的動態訪問權限。
訪問的字段多是一個類(靜態)字段或實例字段。
經常使用方法:
set(Object obj,Object value).
2.動態調用類
能夠根據須要指定要調用的方法,而沒必要在編程時肯定。調用的方法不只權限於public的,還能夠是private。
Method類提供類或接口上單獨某個方法的信息,所反映的方法是類方法或實例方法(包括抽象方法)。它容許在匹配調用的時候實參於底層方法的形參時進行擴輾轉換,
可是若是要進行收縮轉換,則會拋出「非法參數異常」。
使用invoke()。
public Object invoke(Object obj,Object...args)throws IllegalArgumentException,IllegalAccessException,InvocationTargetExcetion
obj--要調用的方法的類對象
args--方法調用的參數 java
Method meth = Math.class.getDeclaredMethod("abs", Integer.TYPE);
Integer a = (Integer) meth.invoke(null, new Integer(-1));編程
3.動態實例化類
Constructor是Java中提供類的單個構造方法的信息以及訪問權限的封裝類。
它容許在將實參與帶有底層構造方法的形參的newInstance()匹配時進行擴輾轉換,
可是若是發生收縮轉換,則拋出IllegalArgumentExcetion。newInstance()方法能夠
使用指定的參數來建立對象:
public T newInstance(Object...initargs)throws InstantiationException,IllegalAccessException,
IllegalArgumentException,InvocationTargetException
initargs: 將做爲變量傳遞給構造方法調用的對象數組。數組
// 動態創建一個String對象,
Constructor<?> construtor = String.class
.getConstructor(String.class);
String str = (String) construtor.newInstance("000123");
4.動態代理
1.實現InvocationHandle 接口
InvocationHandle 接口是代理實例的調用處理程序實現的接口。每一個代理實例都具備一個關聯的調用處理程序。
對代理實例調用方法時,將對方法調用進行編碼並將其指派到它的調用處理程序的invoke()方法:
2.實現invoke()方法方法。
3.實現方法,調用newProxyInstance方法。Proxy.newProxyInstance。
Interface InvocationHandler:該接口中僅定義了一個方法Object:invoke(Object obj,Method method, Object[] args)。
在實際使用時,第一個參數obj通常是指代理類,method是被代理的方法,如上例中的trading(),
args爲該方法的參數數組。這個抽象方法在代理類(代理處理類)中動態實現。
Proxy:該類即爲動態代理類。
Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):
返回代理類的一個實例,返回後的代理類能夠看成被代理類使用 (可以使用被代理類的在接口中聲明過的方法)。
5.Class類的5種方式
java的數據類型能夠分爲兩類,即引用類型和原始類型(即基本數據類型)。
1."Object.getClass()" : 若是一個類的對象可用,則最簡單的得到Class的方法是使用Object.getClass()。
固然,此方式只對引用類型有效。
2. ".class"------------- : 若是類型可用但沒有對象,則能夠在類型後加上".class"來得到Class對象。這也是使原始類型
得到Class對象最簡單的方式:
3."Class.forName()"---: 若是知道類的全名,則可使用靜態方法Class.forName()來得到Class對象,它不能用在原始類型上,
可是能夠用在原始類型數組上。(注:此方式會拋出ClassNotFoundException異常)
4. "包裝類的TYPE域"-----: 每個原始類型和void都有包裝類。利用其TYPE域就能夠得到Class對象。編碼
5."以Class爲返回值的方法": 如獲取內部類的getDeclaredClasses()方法,此時返回一個對象數組
class1 = Class.forName("java.lang.String");代理
6.查看類的定義
一般類的聲明包括常見修飾符(public,protected,private,abstract,static,final,strictfp等)、
類的名稱、類的泛型參數、類的繼承類(實現的接口)、類的註解等信息。
Class類經常使用方法:
forName(String className)-: 根據給定的名稱得到Class對象
getAnnotations()------------: 返回此Class對象上存在的註釋
getCanonicalName() --------: 返回Java Language Specification 中所定義的底層類的規範化名稱
getGenericInterfaces()------: 返回泛型形式的對象類所實現的接口
getGenericSuperclass() -----: 返回泛型形式的對象類所直接繼承的超類
getModifuers() --------------: 返回此類或接口以整數編碼的Java語言修飾符
getTypeParameters() -------: 按聲明順序返回TypeVariable對象的一個數組對象
注:Java語言預約義的註解只有@Deprecated能夠在運行時得到。
7.得到Class對象表示實體的名稱
注:
1.若是此類對象表示的是非數組類型的引用類型,則返回該類的二進制名稱。
2.若是此類對象表示一個基本類型或者void,則返回其對應的Java語言的關鍵字的字符串。
3.若是此類對象表示一個數組類,名字的內部形式爲"[元素編碼",其深度爲幾維,就有幾個"["。
其元素類型編碼爲:
——————————————————————————————————————————————————
元素類型 編 碼
boolean Z
byte B
char C
short S
int I
float F
double D
long J
class or interfaces Lclassname(即當元素是引用類型或者接口的時候,編碼爲"L+類名") 排序
System.out.println("獲取非數組類型的引用類型,返回該類的二進制名稱: "
+ new String().getClass().getName());
8.類的成員
getConstructors() -------: 返回由該類對象的全部構造方法組成的數組
getDeclaredFields() -----: 返回由該類對象的全部非繼承域組成的數組
getDeclaredMethods() -- : 返回由該類對象的全部非繼承方法組成的數組
getFields() -------------- : 返回由該類對象的全部公共域組成的數組
getMethod() -------------: 返回由該類對象的全部公共方法組成的數組繼承
Class<?> strclass = new String().getClass();接口
// 查看構造方法
System.out.println(strclass.getName() + "的構造方法有:");
Constructor<?>[] constructors = strclass.getConstructors();
if (constructors.length > 0) {
for (Constructor<?> constructor : constructors) {
System.out.println("\t" + constructor);
}
} else {
System.out.println("空");
}
9.內部類消息
Class類的getDeclaredClasses()方法返回Class對象的一個數組,這些對象反映聲明爲該Class對象
所表示的類的成員的全部類和接口,包括該類所聲明的公共、保護、默認(包)訪問及私有類和接口,
但不包括繼承的類和接口。若該類不將任何類或接口聲明爲成員,或者該對象表示基本類型、數組類或
void,則該方法返回一個長度爲0的數組。
public Class<?> [] getDeclaredClasses() throws SecurityExceptionci
Class<?> clazz = new String().getClass(); Class[] class1 = clazz.getDeclaredClasses(); for (int i = 0; i < class1.length; i++) { Class<?> innerclass = class1[i]; } 10.繼承層次對類排序 Java提供了instanceof運算符來比較兩個類(或接口)之間是否存在繼承關係。 TreeSet<E> 是基於TreeMap的NavigableSet實現的。它使用元素的天然順序對 元素進行排序,或者根據建立set時提供的Comparator進行排序,具體取決於 使用的構造方法。本節採用Class類中的isAssignableFrom()方法來判斷當前 Class 對象所表示的類與給定的Class對象所表示的類之間的關係,若相同或 是父類則返回true,不然返回false。 public boolean isAssignableFrom(Class<?> clazz) 注:Java中與排序相關的接口有Comparable和Comparator。這兩個接口經過對象之 間比較的結果--一個有符號的整數來比較對象的大小。實現任何一個接口均可 以讓對象具備排序的能力。固能夠用TreeSet也能夠用Arrays.sort()來進行排序。 TreeSet<Class<?>> treeSet = new TreeSet<Class<?>>( new CompareClasses()); System.out.println("添加類——JComponent.class"); treeSet.add(JComponent.class); System.out .println("添加類——Container.class"); treeSet.add(Container.class);