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
代理
接下來我們來看一下代理。
代理可以幫助我們進行很好的封裝,使底層的代碼能夠有效的隱藏起來。
為了區別,我們先來看看靜態代理吧。
這就是靜態代理,理解這個應該不難。
下面我們再來看看動態代理
可以看到動態代理的代理類是實現了一個InvocationHandler的接口,我們通過reflect.Proxy的類的newProxyInstance方法就可以得到這個接口的實例,然后再來作為參數傳遞進去,這里每一個在代理類上處理的東西也會被重定向到調用處理器上。
至于動態代理和靜態代理的區別,即動態代理是動態的創建代理和動態的處理方法的,這也是反射的一個重要體現之處。
總結
以上是生活随笔為你收集整理的Java动态代理与反射详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java动态代理--代理接口无实现类
- 下一篇: Java动态代理的两种实现方法