1. 程式人生 > >框架原理那點事--不就反射嘛。

框架原理那點事--不就反射嘛。

記得之前寫了一篇json轉實體的文章

記得之前寫了一篇json轉實體的文章,裡面就用到了java反射的文章,但是當時只是瞭解到反射這個知識點,並沒有深入的瞭解,寒假閒來無事覺頂深入整理一下java 反射的知識,一下都是個人學習反射的總結,不到之處,還望大神指點!!!

反射顧名思義就是和java編譯相反的過程,這裡實現的效果就是通過類名來進行例項化類物件並對類進行操作。具體看下

獲取父類和所有的介面

  • 首先我們的java類是可以繼承和實現多個介面的,那麼我們如何通過java反射獲取java類的父類和介面呢?

  • 首先我們在這裡新建一個Annimal作為父類

public class Annimal {

    private String AnnimalName;
    
    public void eat(){
        System.out.println("Annimal is eatting");
    }
    public void run(){
        System.out.println("Annimal is running");
    }
}
  • 然後再新建一個Behaviour介面
public interface Behaviour {

    public String haviour="test";
    
    public void sayHello();
    
    public void isAngury();
    
    public void love();
}
  • 現在讓我們新建一個Dog類並讓Dog類繼承Annimal類並實現Behavour這個介面
public class Dog extends Annimal implements Behaviour
  • Dog原始碼
public class Dog extends Annimal implements Behaviour{

    private String dogName;
    
    public void fuck(String name){
        System.out.println("fuck To : "+name);
    }
    @Override
    public void sayHello() {
        // TODO Auto-generated method stub
        System.out.println("Dog sayHello");
    }

    @Override
    public void isAngury() {
        // TODO Auto-generated method stub
        System.out.println("Dog isAngury");
    }

    @Override
    public void love() {
        // TODO Auto-generated method stub
        System.out.println("Dog love");
    }

}
  • 測試

  • 下面我們開始進行測試,首先我們通過Class類來獲取類的class物件

Class<?> target=Class.forName("tom.change.Reflect.獲取父類和所有介面.Dog");

  • 然後通過getSuperClass和getInterfaces這兩個方法就可以獲取到父類和所有的介面
//獲取Dog類的父類
Class<?> parent=target.getSuperclass();
//獲取該類繼承的所有類
Class<?> intefaces[]=target.getInterfaces();
  • 最後看程式執行的效果圖

獲取所有的屬性(getDeclaredFields)

  • 在Java類中出了類與類中關係,每個類還有具有特定的屬性,那麼我們如何通過反射來獲取Java類中的屬性呢。下面我寫了一個user類,其中的屬性為

Dog類:

    private String dogName;
  • 那麼下面我們來試試到底能不能獲取上面的幾個屬性。同樣通過類路徑獲取class物件
Class<?> clazz=Class.forName("tom.change.Reflect.獲取父類和所有介面.Dog");
  • 然後通過class物件的getDeclaredFields方法獲取本地類的屬性,這個方法是無法獲取繼承父類和介面中的屬性,如果非要獲取你可以先通過該類獲取到父類,然後在去獲取父類的class 物件,在去獲取父類中屬性。
for (int i = 0; i < fields.length; i++) {
            //獲取欄位的修飾許可權符
            System.out.println(Modifier.toString(fields[i].getModifiers())+"@@@"+fields[i].getName());
        }
  • 這裡說一下,獲取後用Field 來接受,這個類getModifiers是獲取該屬性的屬性的,私有還是公共還是保護的。

  • 這裡獲取欄位後,通過Field的set方法就可以給屬性設定,不管屬性的對外狀態。前提是開啟許可權

field.setAccessible(true);
field.set(object, "21131084");
  • 這裡的object是class的一個例項化物件

獲取類中的所有的方法(getMethods)

  • 在上面我們已經獲取了類中所有的屬性,那麼下面我們自然就是獲取類中的所有的方法了。同樣的步驟上面已經有了,這裡不贅述了,只不過和上面的不同的地方就是獲取class物件後我們呼叫getMethods方法。
public void tom.change.Reflect.獲取父類和所有介面.Dog.fuck(java.lang.String)
public void tom.change.Reflect.獲取父類和所有介面.Dog.sayHello()
public void tom.change.Reflect.獲取父類和所有介面.Dog.love()
public void tom.change.Reflect.獲取父類和所有介面.Dog.isAngury()
public void tom.change.Reflect.獲取父類和所有介面.Annimal.run()
public void tom.change.Reflect.獲取父類和所有介面.Annimal.eat()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
  • 大家有沒有疑問,為什麼有一些莫名的方法出現,有些方法甚至我們的Dog和繼承類中都沒有出現過,這是怎麼回事呢。首先getMethods獲取類本身的方法這是肯定的。繼承的類我們也是可以獲取的,這就解釋了為什麼我們的獲取方法中有Annimal類中的方法,。那麼後面那些Object類的方法是哪裡來的呢,大家還記得嗎所有的類都是繼承Object類的。

類中方法的呼叫(getMethod)

  • 在上面我們獲取了方法後,通過getMethod獲取指定的方法,該方法返回的是Method物件,然後通過Method裡的invoke方法呼叫指定的方法。在呼叫的時候需要傳入class實力化物件,有引數的話我們還需要傳入引數。
public Object invoke(Object obj, Object... args)
  • 原始碼顯示,方法需要引數有多少這裡就傳入多少,這裡是通用的。

  • 在通過getMethod獲取Method的時候我們需要傳入方法引數的型別

```
public Object invoke(Object obj, Object... args)
```

```
public Method getMethod(String name, Class<?>... parameterTypes)
```

獲取所有建構函式(getConstructors)

  • Java類中最後應該還剩下構造函數了,既然是反射,我們就要將類反射的乾乾晶晶的。獲得class物件後我們通過getConstructors獲取建構函式,該方法返回的是Constructor集合。在Constructor類中getParameterTypes獲取建構函式中的引數,有個這個我們就可以自己進行類的構造了。

總結

  • 到這裡我們的反射已經完全可以操作一個類了。有人會問這有啥意思呢,在我們Javaweb中,哪些知名的框架原始碼裡必須有反射,通過反射我們能夠實現註解這個功能。當然註解還有其他知識,以後知道在介紹。再比如說我們將map與實體進行對映這裡就需要反射區獲取Java Bean中的屬性並將map的值賦值。不管怎麼樣,反射是我們Java的重要知識,學會它對自己以後的架構方面試有很大的幫助的。

原始碼下載

加入戰隊

# 加入戰隊

微信公眾號

相關推薦

框架原理--反射

記得之前寫了一篇json轉實體的文章 記得之前寫了一篇json轉實體的文章,裡面就用到了java反射的文章,但是當時只是瞭解到反射這個知識點,並沒有深入的瞭解,寒假閒來無事覺頂深入整理一下java 反射的知識,一下都是個人學習反射的總結,不到之處,還望大神指點!!! 反射顧名思義就是和java編譯相反的過程

關於驅動隱藏(觸發PG 支援win10)

沒必要藏著,人生沒有必要為這些小玩意小打小鬧。 看到某些哥們這搞搞那搞搞,BSOD PATCHGUARD 無語,WRK是個好東西啊! 還有半年來也沒怎麼發部落格,慚愧慚愧。 驅動隱藏 最經典的就是斷鏈來一發 但是這個不行 原因我就不說了 網上有的方法 1.斷鏈

【Java那點事 | 學習●思考●分享 | Java技術交流QQ群:83753349】當你的才華還撐起你的野心時,應該靜下心來學習豈能盡如人意,但求無愧我心; 努力一定會成功,但是放棄一定會失敗; 好好學習,天天向上,求與人相比,但求超越

當你的才華還撐不起你的野心時,那你就應該靜下心來學習。豈能盡如人意,但求無愧我心; 努力不一定會成功,但是放棄一定會失敗; 好好學習,天天向上,不求與人相比,但求超越自己; 知其然,還要知其所以然;...

日誌框架

日誌框架介紹 一、簡介 日誌框架 市場上存在非常多的日誌框架。JUL(java.util.logging),JCL(Apache Commons Logging),Log4j,Log4j2,Logback、SLF4j、jboss-logging等。 Spring Boot在框架內

Spring Mvc---(36)rest服務框架搭建

引子   隨著網際網路的發展,大資料的出現,資料間的互動越來越多的以服務形式展現。服務的展現互動形式也越來越多,例如http,tcp.udp等,並且有許多現成的服務框架供我們使用,比如webservice, wcf, dubbo服務,rest服務等. springmvc

java——StringBuffer與StringBuilder原理與區別

37~42都是進入for迴圈前的一些準備工作,37,38是將j置為1。44這裡通過if_icmpge將j與10進行比較,如果j大於10則直接跳轉到73,也即return語句退出函式;否則進入迴圈,也即47~66的位元組碼。這裡我們只需看47到51就知道為什麼我們要在程式碼中自己使用StringBuffer來處

「數據治理」系列之三:忘初心方得始終,數據質量管理要穩住!

規劃 分組 質量 管理 決策者 出發 遇到 例子 評估 文 | 樂天(原創)未經許可,不可轉載。 編輯 | 劉能 碳酸 本文約 3209 字,預計閱讀時間 9 分鐘 作者簡介:蔣珍波(樂天),6 年+ 大數據咨詢經驗,擅長為客戶提供科學合理的大數據解決方案。目前擔任數瀾科

爬蟲,幹玩了之seleunim

目錄 selenium 環境準備 程式碼環境 開始爬蟲 操作js 截圖 切換視窗 在當前視窗切換訪問地址 管理cookie

Dubbo Cluster叢集知道的

這是why技術的第33篇原創文章 本週是在家辦公的一週,上面的圖就是我在家的工位。 工欲善其事,必先利其器。在家辦公,我是認真的。 在家裡開發的時候有需求是這樣的:一個如果介面呼叫失敗,需要自動進行重試。 雖然關係不大,但是我還是想到了Dubbo的叢集容錯策略:Failover Cluster,即失敗自動

設計模式--策略模式

簡化 cas enter ext font 想要 fonts 對象創建 客戶 概念: 策略模式定義了一系列的算法,分別封裝起來,讓它們之間能夠相互替換。此模式讓算法的變化,不會影響到使用算法的客戶。策略,實質上指的是算法。 樣例

談談字符串

沒有 register 用戶 今後 過程 破解 插件 運行 tro 在od破解軟件過程中,大家對於字符串應該是再熟悉不過了,但是往往事情不盡如人意,總是搜索不到想要的字符串,這時往往有的人會被迫用別的方法,消息斷點,內存斷點,硬件斷點等等,今天咱們只談字符串,把我所掌握的查

浮點數的

bsp 用兩個 處理 有一個 奇葩 加減乘 而且 出了 判斷 浮點數是計算機中儲存實數的形式。我們時常需要用浮點數去處理帶小數點的運算。可你是否知道,浮點數還有這些操作: 正負無窮大 與整數不同,浮點數沒有溢出的概念。當浮點數的運算結果超過一定範圍時,它的值就會根據運算結

新手···男生

for take edit ger har ping minutes lazy sgu 1、alarm clock go off鬧鐘響了,sleep right through it睡過去了,time to get up該起床, 2、you name it你說的 3、sle

mongodb第二篇文章~關於集群認證的

所有 目的 create 介紹 副本 這就是我 port pwd root 集群認證簡介:上一篇咱們介紹了單實力的認證方式,正好我在搞lepus監控,副本集合需要用戶認證 一 驗證方式: 1 auth 方式啟動=》單點 2 keyFile 方式啟動=》集群 請註意 開

PostgreSql(文件讀取寫入、命令執行的辦法)

ict con ext ews none urn truct 語法 tip ? 2013/07/9 作者: admin PostgreSql那點事(文件讀取寫入、命令執行的辦法) 今天無意發現了個PostgreSQL環境,線上學習了下,一般的數據註射(讀寫數據庫)差異不

搭建Maven私服

文件的 repos 版本控制工具 oracl 手工 apach security 項目 源碼 摘要:本文主要介紹在CentOS7.1下使用nexus3.6.0搭建maven私服,以及maven私服的使用(將自己的Maven項目指定到私服地址、將第三方項目jar上傳到私服供

this的

this指向 st2 開始 light pre 全局對象 很多 var 同時 對於很多初學者,this總是搞得我們暈頭轉向。 現在,我就簡單的總結一下關於this的那點事。 this在函數定義時經常是不能確定的,只有在函數執行的時候才能最終確定this的歸屬。this總是指

net 自定義泛型

toolbar user 定義和使用 程序 參考 關鍵字 double png 不同 泛型概述 泛型是程序設計語言的一種特性。允許程序員在強類型程序設計語言中編寫代碼時定義一些可變部分,那些部分在使用前必須作出指明。各種程序設計語言和其編譯器、運行環境對泛型的支持均不一樣

C#編譯器優化

代碼質量 配置 需要 但是 strong -a tool -- dbo 使用C#編寫程序,給最終用戶的程序,是需要使用release配置的,而release配置和debug配置,有一個關鍵區別,就是release的編譯器優化默認是啟用的。 優化代碼開關即optimize開關

Android8.0適配(一)

懸浮 新增功能 nta onstop config ges 保持 com dfa 1、通知渠道(Channeld) 當然,適配8.0的第一步自然是把targeSdk升級到26,在8.0中所有通知的實現都需要提供通知渠道,否則,所有通知在8.0系統上面都不能正常顯示; 下圖是