日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java动态代理与反射详解

發布時間:2024/2/28 java 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java动态代理与反射详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載自?https://www.cnblogs.com/haodawang/p/5967185.html

首先我得先請大家不要誤會,博客園說轉載的文章放在文章分類里,原創的文章用隨筆寫,我開先還以為隨筆是拿來寫抒情文的(滑稽),后來才發現不是這樣的,但是自己所有的文章都在文章分類里了,又懶得搬運,所以我就用js重定向了一下。所以現在標題欄里進來的都是文章分類哦,大部分都是自己原創的,轉載會注明轉載的url。

廢話不多說,今天我想來聊一下java里的反射和動態代理的問題,因為這兩個東西實在撩人,而且動態代理百度幾乎都是千篇一律,今天我寫這篇博文希望能幫助大家,順便也是為了鞏固自己,畢竟自己也折騰了好久。

先來看看反射。
java里的class文件加載分為兩種情況,一種就是類型是編譯器已知的,這種文件的.class文件在編譯的時候,編譯器會把.class文件打開檢查,但是注意不是加載哦,第二種就是我們可能是從別的地方獲取到了一個引用,然后動態的把這個未知類型的引用的對象的.class文件加載進jvm虛擬機里。

那么我們稱前者為RTTI,即Run- Time Type Identification 運行時類型識別,有的人把RTTI翻譯成 Run - Time Type Information ,我個人認為是不對的,因為我覺得它概括的不夠全面,所以我建議大家把I 翻譯成Identification更容易理解。

我們稱后者為“反射”,這對于正在學習JAVA的人來說可是一個新的名詞,但反射也是作為一個java的核心技術的存在。下面就來看看反射究竟有多重要吧。

反射

在java里提供了一個叫做reflect的庫,這個庫里封裝了Method,Constructor,field,Proxy,InvocationHandler 等類,這些類的API在我們學習反射會很有幫助。

反射最大的作用就在于我們可以不在編譯時知道某個對象的類型,而在運行時得到。同時我們只需要得到我們想得到的類的名字即可(如果不在一個包,必須寫完整的名字包括包名)。

package com.bike;import java.lang.reflect.*;public class Main {public static void main(String[] args) throws Exception{//返回A的構造方法Constructor c = A.class.getConstructor();//返回A類的所有為public 聲明的構造方法Constructor[] cons = A.class.getConstructors();//返回A類所有的構造方法,包括privateConstructor[] cons2 = A.class.getDeclaredConstructors();//返回A類的第一個public 方法Method m = A.class.getMethod("say");//執行m.invoke(A.class.newInstance(), null);//返回A類所有的public 方法Method[] ms = A.class.getMethods();//返回A類所有的方法,包括privateMethod[] allMs = A.class.getDeclaredMethods();//返回A類的public字段Field field = A.class.getField("i");System.out.println(field.get(A.class.newInstance()));//返回A類的static 字段System.out.println(field.get(null));} }class A{public int i = 1;public static int b = 2;public A(){System.out.println("無參構造");}private A(String s){System.out.println("有參構造"+s);}public void say(){System.out.println("say");} }

這里我只是簡單的把API羅列了一下,大家可以自己動手試試,我這里就不再去描述了。
通過上面的例子我們可以看出我們只用知道一個類的名字便可以得知它內部方法和字段,那么這里已經強烈的體現到了反射的作用。只是我這里做例子的時候把A作為了自己內部包的一個類,而在實際開發中,你可能是跨包的,所以你必須要寫上全名才行。

關于.class類字面常量的知識請參照我的上一篇博文:http://www.cnblogs.com/haodawang/articles/5954368.html

代理

接下來我們來看一下代理。
代理可以幫助我們進行很好的封裝,使底層的代碼能夠有效的隱藏起來。
為了區別,我們先來看看靜態代理吧。

public class Main2 {//這里傳入的是接口類型的對象,方便向上轉型,實現多態public static void consumer(ProxyInterface pi){pi.say();}public static void main(String[] args) {// TODO Auto-generated method stubconsumer(new ProxyObject());} }//代理接口 interface ProxyInterface{public void say(); }//被代理者 class RealObject implements ProxyInterface{//實現接口方法@Overridepublic void say() {// TODO Auto-generated method stubSystem.out.println("say");}}//代理者 class ProxyObject implements ProxyInterface{@Overridepublic void say() {// TODO Auto-generated method stub//dosomething for exampleSystem.out.println("hello proxy");new RealObject().say();System.out.println("this is method end");}} output: hello proxy say this is method end

這就是靜態代理,理解這個應該不難。
下面我們再來看看動態代理

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方法就可以得到這個接口的實例,然后再來作為參數傳遞進去,這里每一個在代理類上處理的東西也會被重定向到調用處理器上。

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


總結

以上是生活随笔為你收集整理的Java动态代理与反射详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。