1. 程式人生 > >JAVA的回撥函式和反射機制(原理不說直接看程式碼),補充動靜態代理

JAVA的回撥函式和反射機制(原理不說直接看程式碼),補充動靜態代理

程式碼都是轉載或抄錄這個地址:

http://blog.csdn.net/zhandoushi1982/article/details/8567709

http://blog.csdn.net/xiaanming/article/details/8703708/

反射機制

public class main { 
	
	public void test(int x){
		System.out.println(x);
	}
	
	public static void main(String[] args) throws  ClassNotFoundException, NoSuchFieldException, Exception{
/*
		Class<?> forName = Class.forName("main");
		Method method = forName.getDeclaredMethod("test", Integer.class);
		method.invoke(forName.newInstance(), 10);
*/

		Class<?> forName1 = Class.forName("main");
		Method method1 = forName1.getDeclaredMethod("test", int.class);
		method1.invoke(forName1.newInstance(), 10); 

	}
}

回撥函式&函式回撥&回撥機制

所謂回撥:就是A類中呼叫B類中的某個方法C,然後B類中反過來呼叫A類中的方法D,D這個方法就叫回調方法

/** 
 * 這是一個回撥介面 
 * @author xiaanming 
 * 
 */  
public interface CallBack {  
    /** 
     * 這個是小李知道答案時要呼叫的函式告訴小王,也就是回撥函式 
     * @param result 是答案 
     */  
    public void solve(String result);  
}  

/** 
 * 這個是小王 
 * @author xiaanming 
 * 實現了一個回撥介面CallBack,相當於----->背景一 
 */  
public class Wang implements CallBack {  
    /** 
     * 小李物件的引用 
     * 相當於----->背景二 
     */  
    private Li li;   
  
    /** 
     * 小王的構造方法,持有小李的引用 
     * @param li 
     */  
    public Wang(Li li){  
        this.li = li;  
    }  
      
    /** 
     * 小王通過這個方法去問小李的問題 
     * @param question  就是小王要問的問題,1 + 1 = ? 
     */  
    public void askQuestion(final String question){  
        //這裡用一個執行緒就是非同步,  
        new Thread(new Runnable() {  
            @Override  
            public void run() {  
                /** 
                 * 小王呼叫小李中的方法,在這裡註冊回撥介面 
                 * 這就相當於A類呼叫B的方法C 
                 */  
                li.executeMessage(Wang.this, question);   
            }  
        }).start();  
          
        //小網問完問題掛掉電話就去幹其他的事情了,誑街去了  
        play();  
    }  
  
    public void play(){  
        System.out.println("我要逛街去了");  
    }  
  
    /** 
     * 小李知道答案後呼叫此方法告訴小王,就是所謂的小王的回撥方法 
     */  
    @Override  
    public void solve(String result) {  
        System.out.println("小李告訴小王的答案是--->" + result);  
    }  
      
}  

/** 
 * 測試類 
 * @author xiaanming 
 * 
 */  
public class Test {  
    public static void main(String[]args){  
        /** 
         * new 一個小李 
         */  
        Li li = new Li();  
  
        /** 
         * new 一個小王 
         */  
        Wang wang = new Wang(li);  
          
        /** 
         * 小王問小李問題 
         */  
        wang.askQuestion("1 + 1 = ?");  
    }  
} 

這個例子採用非同步加回調
轉載http://www.cnblogs.com/haodawang/p/5967185.html
動態代理,靜態代理看上面連結
import java.lang.reflect.*;

public class Main {
    static void customer(ProxyInterface pi){
        pi.say();
    }
    public static void main(String[] args){
        RealObject real = new RealObject();
        ProxyInterface proxy = (ProxyInterface)Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(),new Class[]{ProxyInterface.class}, new ProxyObject(real));
        customer(proxy);
    }
}


interface ProxyInterface{
    void say();
}

//被代理類
class RealObject implements ProxyInterface{
    public void say(){
        System.out.println("i'm talking");
    }
}

//代理類,實現InvocationHandler 介面
class ProxyObject implements InvocationHandler{
    private Object proxied = null;
    public ProxyObject(){
        
    }
    public ProxyObject(Object proxied){
        this.proxied  = proxied;
    }
    public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
        System.out.println("hello");
        return arg1.invoke(proxied, arg2);
    };
}
以下摘抄:

可以看到動態代理的代理類是實現了一個InvocationHandler的介面,我們通過reflect.Proxy的類的newProxyInstance方法就可以得到這個介面的例項,然後再來作為引數傳遞進去,這裡每一個在代理類上處理的東西也會被重定向到呼叫處理器上。

至於動態代理和靜態代理的區別,即動態代理是動態的建立代理和動態的處理方法的,這也是反射的一個重要體現之處。