1 JAVA的反射,其實就是通過一個執行個體化的對象反過來去找到一個類的完整資訊,比如對於如下的形式:
X x=new X();
x.getClass().getName();
這裡就會輸出這個類所在的完整資訊,即"包名.類名";
最常用的三種執行個體化CLASS類對象
Class<?> c1 = null ; // 指定泛型
Class<?> c2 = null ; // 指定泛型
Class<?> c3 = null ; // 指定泛型
try{
// 以下的操作形式是在開發中最常用的一種形式
c1 = Class.forName("org.lxh.demo15.getclassdemo.X") ;
}catch(ClassNotFoundException e){
e.printStackTrace() ;
}
c2 = new X().getClass() ; // 通過Object類中的方法執行個體化
c3 = X.class ; // 通過類.class執行個體化
System.out.println("類名稱:" + c1.getName()) ; // 得到類的名稱
System.out.println("類名稱:" + c2.getName()) ; // 得到類的名稱
System.out.println("類名稱:" + c3.getName()) ; // 得到類的名稱
2 通過無參構造執行個體化對象
假設有個類,其中必須存在一個無參數的建構函式,則可以用如下的這個方式進行
Class<?> c = null ; // 聲明Class對象
try{
c = Class.forName("org.lxh.demo15.instancedemo.Person") ;
}catch(ClassNotFoundException e){
e.printStackTrace() ;
}
Person per = null ; // 聲明Person對象
try{
per = (Person)c.newInstance() ; // 執行個體化對象
}catch(Exception e){
e.printStackTrace() ;
}
如果類中是存在有參數的建構函式的話,則用如下方式實現:
Class<?> c = null ; // 聲明Class對象
try{
c = Class.forName("org.lxh.demo15.getclassdemo.Person") ;
}catch(ClassNotFoundException e){
e.printStackTrace() ;
}
Person per = null ; // 聲明Person對象
Constructor<?> cons[] = null ;
cons = c.getConstructors() ;
try{
per = (Person)cons[0].newInstance("李興華",30) ; // 執行個體化對象
}catch(Exception e){
e.printStackTrace() ;
}
這裡是通過類中的getConsructors()取得本類中的全部構造方法.
3 取得類的結構:
A 取得類中的全部介面:
Class<?> c[] = c1.getInterfaces() ; // 以數組形式返回實現的全部介面
for(int i=0;i<c.length;i++){
System.out.println("實現的介面名稱:" + c[i].getName()) ; // 輸出介面名稱
}
B 取得父類
Class<?> c2 = c1.getSuperclass() ; // 取得父類
C 取得全部的構造方法,並且通過modifier類修飾符來獲得
import java.lang.reflect.Constructor ; // 匯入構造方法的包
import java.lang.reflect.Modifier ; // 匯入構造方法的包
public class GetConstructorDemo03{
public static void main(String args[]){
Class<?> c1 = null ; // 聲明Class對象
try{
c1 = Class.forName("org.lxh.demo15.Person") ; // 執行個體化對象
}catch(ClassNotFoundException e){
e.printStackTrace() ;
}
Constructor<?> con[] = c1.getConstructors() ; // 取得一個類中的全部構造
for(int i=0;i<con.length;i++){
Class<?> p[] = con[i].getParameterTypes() ; // 得到構造方法中的全部
參數
System.out.print("構造方法:" ) ; // 輸出構造,直接列印
int mo = con[i].getModifiers() ; // 得到所要的存取權限
System.out.print(Modifier.toString(mo) + " ") ; // 得到修飾符
System.out.print(con[i].getName()) ; // 取得構造方法的名字
System.out.print("(") ;
for(int j=0;j<p.length;j++){
System.out.print(p[j].getName() + " arg" + i) ;
if(j<p.length-1){
// 判斷此是否是最後一個參數
System.out.print(","); // 輸出“,”
}
}
System.out.println("){}") ;
}
}
}
D 取得一個類的全部構造方法
public class GetMethodDemo{
public static void main(String args[]){
Class<?> c1 = null ; // 聲明Class對象
try{
c1 = Class.forName("org.lxh.demo15.Person") ; // 執行個體化對象
}catch(ClassNotFoundException e){
e.printStackTrace() ;
}
Method m[] = c1.getMethods() ; // 取得全部方法
for(int i=0;i<m.length;i++){
Class<?> r = m[i].getReturnType() ; // 得到傳回值類型
Class<?> p[] = m[i].getParameterTypes() ; // 取得全部參數的類型
int xx = m[i].getModifiers() ; // 得到修飾符
System.out.print(Modifier.toString(xx) + " ") ; // 輸出修飾符
System.out.print(r + " ") ;
System.out.print(m[i].getName()) ;
System.out.print("(") ;
for(int j=0;j<p.length;j++){
System.out.print(p[j].getName() + " " + "arg" + j) ;
if(j<p.length-1){
System.out.print(",") ;
}
}
Class<?> ex[] = m[i].getExceptionTypes() ; // 取出異常
if(ex.length>0){
System.out.print(") throws ") ;
}else{
System.out.print(")") ;
}
for(int j=0;j<ex.length;j++){
System.out.print(ex[j].getName()) ;
if(j<p.length-1){
System.out.print(",") ;
}
}
System.out.println() ;
}
}
}
4 通過反射調用類中的方法
Class<?> c1 = null ;
try{
c1 = Class.forName("org.lxh.demo15.Person") ; // 執行個體化Class對象
}catch(Exception e){}
try{
Method met = c1.getMethod("sayChina") ; // 找到sayChina()方法
met.invoke(c1.newInstance()) ; // 調用方法
}catch(Exception e){
e.printStackTrace() ;
}
}
如果要調用有參數的
Class<?> c1 = null ;
try{
c1 = Class.forName("org.lxh.demo15.Person") ; // 執行個體化Class對象
}catch(Exception e){}
try{
Method met = c1.getMethod("sayHello",String.class,int.class) ; // 找到sayChina
()方法
String rv = null ;
rv = (String)met.invoke(c1.newInstance(),"李興華",30) ; // 調用方法
System.out.println(rv) ;
}catch(Exception e){
e.printStackTrace() ;
}
}
5 利用反射配合原廠模式
package org.lxh.demo15.factorydemo02 ;
import java.util.Properties ;
import java.io.File ;
import java.io.FileOutputStream ;
import java.io.FileInputStream ;
interface Fruit{
public void eat() ; // 吃水果
}
class Apple implements Fruit{
public void eat(){ // 覆寫eat()方法
System.out.println("** 吃蘋果");
}
};
class Orange implements Fruit{
public void eat(){
System.out.println("** 吃橘子") ;
}
};
class Init{
public static Properties getPro(){
Properties pro = new Properties() ;
File f = new File("d:\\fruit.properties") ; // 找到屬性檔案
try{
if(f.exists()){ // 檔案存在
pro.load(new FileInputStream(f)) ; // 讀取屬性
}else{
pro.setProperty("apple","org.lxh.demo15.factorydemo02.Apple") ;
pro.setProperty("orange","org.lxh.demo15.factorydemo02.Orange") ;
pro.store(new FileOutputStream(f),"FRUIT CLASS") ;
}
}catch(Exception e){}
return pro ;
}
};
class Factory{
public static Fruit getInstance(String className){
Fruit fruit = null ;
try{
fruit = (Fruit)Class.forName(className).newInstance() ;
}catch(Exception e){
e.printStackTrace() ;
}
return fruit ;
}
};
public class FactoryDemo02{
public static void main(String args[]){
Properties pro = Init.getPro() ;
Fruit f = Factory.getInstance(pro.getProperty("apple")) ;
if(f!=null){
f.eat() ;
}
}
};
6 動態代理:
import java.lang.reflect.InvocationHandler ;
import java.lang.reflect.Proxy ;
import java.lang.reflect.Method ;
interface Subject{
public String say(String name,int age) ; // 定義抽象方法say
}
class RealSubject implements Subject{ // 實現介面
public String say(String name,int age){
return "姓名:" + name + ",年齡:" + age ;
}
};
class MyInvocationHandler implements InvocationHandler{
private Object obj ;
public Object bind(Object obj){
this.obj = obj ; // 真實主題類
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass
().getInterfaces(),this) ;
}
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
Object temp = method.invoke(this.obj,args) ; // 調用方法
return temp ;
}
};
public class DynaProxyDemo{
public static void main(String args[]){
Subject sub = (Subject)new MyInvocationHandler().bind(new RealSubject()) ;
String info = sub.say("李興華",30) ;
System.out.println(info) ;
}
};