1. 程式人生 > >java反射使用舉例(全)

java反射使用舉例(全)

本文將敘述如何執行時檢視類資訊,其中包括變數,方法,以及通過反射修改變數,執行方法等

包括如何反射匿名內部類及如何執行其方法,但是筆者強烈不建議這麼做,這裡只是演示反射而已

下面是一個測試類

Java程式碼  收藏程式碼
  1. package reflect;  
  2. public class Outer {  
  3.     static{  
  4.         System.out.println("Testing..");  
  5.     }  
  6.     TestInterface ti = new TestInterface() {  
  7.         public
     String test() {  
  8.             return "this is ti";  
  9.         }  
  10.     };  
  11.     public Outer(String name){  
  12.         System.out.println("Outer");  
  13.     }  
  14.     public String toString(){  
  15.         System.out.println("Outer toString");  
  16.         return new TestInterface() {  
  17.             public
     String test() {  
  18.                 return "this is a test!";  
  19.             }  
  20.         }.test();  
  21.     }  
  22.     @SuppressWarnings("unused")  
  23.     private void privateMethod(){  
  24.         System.out.println("privateMethod");  
  25.     }  
  26.     protected void protectedMethod(){  
  27.         System.out.println("protectedMethod"
    );  
  28.     }  
  29.     void packageMethod(){  
  30.         System.out.println("packageMethod");  
  31.     }  
  32.     public static void staticMethod(){  
  33.         System.out.println("staticMethod");  
  34.     }  
  35.     public interface TestInterface {  
  36.         public String test();  
  37.     }  
  38.     public static class StaticInner {  
  39.         private static final String TAG = "StaticInnerTAG";  
  40.         public StaticInner(){  
  41.             System.out.println("StaticInner");  
  42.         }  
  43.         public String toString(){  
  44.             System.out.println("StaticInner toString");  
  45.             return TAG;  
  46.         }  
  47.     }  
  48.     private class Inner{  
  49.         String name;  
  50.         public Inner(){  
  51.             System.out.println("Inner");  
  52.         }  
  53.         public Inner(String name){  
  54.             System.out.println("reflect.Outer.Inner.Inner(String name)");  
  55.             this.name = name;  
  56.         }  
  57.     }  
  58. }  

其中包括了普通內部類,靜態內部類,內部匿名類,介面等

其中外部類Outer沒有預設構造器,String reflect.Outer.Inner.getName()是private的……

外部類

Constructor,Method,Class.forName,newInstance

下面來看如何對上述的類進行反射

首先先看外部類Outer

Java程式碼  收藏程式碼
  1. public static void main(String[] args) {  
  2.     try {  
  3.         Class<?> outer = Class.forName("reflect.Outer");  
  4.         outer = Outer.class;  
  5.         Constructor<?>[] constructors = outer.getConstructors();  
  6.         for (Constructor<?> constructor : constructors) {  
  7.             Class<?>[] types = constructor.getParameterTypes();  
  8.             System.out.println(constructor.getName() + "(" + arrayToString(types) + ")");  
  9.         }  
  10.         Constructor<?> outerConstructor = outer.getConstructor(String.class);  
  11.         Outer outerInstance = (Outer) outerConstructor.newInstance("a outer");  
  12.         System.out.println(outerInstance);  
  13.     } catch (ClassNotFoundException e) {  
  14.         e.printStackTrace();  
  15.     } catch (SecurityException e) {  
  16.         e.printStackTrace();  
  17.     } catch (NoSuchMethodException e) {  
  18.         e.printStackTrace();  
  19.     } catch (IllegalArgumentException e) {  
  20.         e.printStackTrace();  
  21.     } catch (InstantiationException e) {  
  22.         e.printStackTrace();  
  23.     } catch (IllegalAccessException e) {  
  24.         e.printStackTrace();  
  25.     } catch (InvocationTargetException e) {  
  26.         e.printStackTrace();  
  27.     }  
  28. }  
  29. public static String arrayToString(Class<?>[] classes){  
  30.     StringBuilder stringBuilder = new StringBuilder();  
  31.     for (Class<?> type : classes) {  
  32.         stringBuilder.append(type.getCanonicalName());  
  33.         stringBuilder.append(",");  
  34.     }  
  35.     if(classes.length > 0){  
  36.         stringBuilder.deleteCharAt(stringBuilder.length() - 1);  
  37.     }  
  38.     return stringBuilder.toString();  
  39. }  

列印結果

Java程式碼  收藏程式碼
  1. Testing..  
  2. reflect.Outer(java.lang.String)  
  3. Outer  
  4. Outer toString  
  5. this is a test!  

下面簡單分析下

Java程式碼  收藏程式碼
  1. Class<?> outer = Class.forName("reflect.Outer");  
  2. //outer = Outer.class;  

我們對類reflect.Outer進行反射,這裡使用Outer.class也可以獲得Class物件

之前說過使用類字面量不會初始化該類,而Class.forName則會初始化 ,當使用Outer.class時候log如下

Java程式碼  收藏程式碼
  1. reflect.Outer(java.lang.String)  
  2. Testing..  
  3. Outer  
  4. Outer toString  
  5. this is a test!  

順序改變了,列印的時候Testing..實際是下面這句觸發的

Java程式碼  收藏程式碼
  1. Outer outerInstance = (Outer) outerConstructor.newInstance("a outer");  

這時候載入Outer這個類,然後進行初始化

接下來我們查看了Outer的所有構造器Constructor,並打印出所需要的引數(與普通方法區別開來)

構造器只有一個,引數是String

如何執行這個帶有String作為引數的構造器來返回一個Outer例項

Java程式碼  收藏程式碼
  1. Constructor<?> outerConstructor = outer.getConstructor(String.class);  
  2. Outer outerInstance = (Outer) outerConstructor.newInstance("a outer");  
  3. System.out.println(outerInstance);  

我們先取得我們需要的Constructor,然後,Constructor提供了newInstance方法,這樣就可以獲得Outer例項

最後列印例項,呼叫了toString函式

如果你嘗試呼叫

Java程式碼  收藏程式碼
  1. outer.newInstance();   

則會看到如下異常

java.lang.InstantiationException: reflect.Outer

 at java.lang.Class.newInstance0(Class.java:357)

 at java.lang.Class.newInstance(Class.java:325)

 at reflect.Test.main(Test.java:30)

這是因為Outer沒有提供預設構造器

在獲得Constructor時其實是有下面兩個選擇的,至於區別,我們放在Method裡說

Java程式碼  收藏程式碼
  1. outer.getConstructors();  
  2. outer.getDeclaredConstructors()  

現在看看如何獲得類的方法,順便看看Declared的作用

不如直接打印出來,這樣比較直觀

Java程式碼  收藏程式碼
  1. Method[] methods = outer.getMethods();  
  2. for (Method method : methods) {  
  3.     Class<?>[] types = method.getParameterTypes();  
  4.     System.out.println(method.getReturnType().getName() + " " + outer.getName() + "." + method.getName() + "(" + arrayToString(types) + ")");  
  5. }  
  6. System.out.println("--------------------------------------");  
  7. methods = outer.getDeclaredMethods();  
  8. for (Method method : methods) {  
  9.     Class<?>[] types = method.getParameterTypes();  
  10.     System.out.println(method.getReturnType().getName() + " " + outer.getName() + "." + method.getName() + "(" + arrayToString(types) + ")");  
  11. }Class<?> outer = Outer.class;  

結果如下

Java程式碼  收藏程式碼
  1. void reflect.Outer.staticMethod()  
  2. java.lang.String reflect.Outer.toString()  
  3. void reflect.Outer.wait(long)  
  4. void reflect.Outer.wait()  
  5. void reflect.Outer.wait(long,int)  
  6. boolean reflect.Outer.equals(java.lang.Object)  
  7. int reflect.Outer.hashCode()  
  8. java.lang.Class reflect.Outer.getClass()  
  9. void reflect.Outer.notify()  
  10. 相關推薦

    java反射使用舉例

    本文將敘述如何執行時檢視類資訊,其中包括變數,方法,以及通過反射修改變數,執行方法等 包括如何反射匿名內部類及如何執行其方法,但是筆者強烈不建議這麼做,這裡只是演示反射而已 下面是一個測試類 Java程式碼   package 

    Java系列文章

    java 學習JVMJVM系列:類裝載器的體系結構 JVM系列:Class文件檢驗器JVM系列:安全管理器JVM系列:策略文件Java垃圾回收機制深入剖析Classloader(一)--類的主動使用與被動使用深入剖析Classloader(二)-根類加載器,擴展類加載器與系統類加載器深入理解JVM—JVM內存

    Java反射應用1

    Java反射應用 1:前臺到後臺資料自動裝入物件 2:poi中寫個通用poi工具類,作用是自動將引數裝入到到excel單元格中 在傳統的寫法就是需要將資料來源每列資料都一個個裝入到excel沒每個單元格中。 注意:這裡主要詳細講解第1個,因為poi通用工具類還需要優化,以後再開反射

    Java效能提示

    AWT components are not useful as game actors (sprites) as they do not overlap well, nor are they good at being moved around the screen. Celled image fil

    Java-反射機制reflection

    一.概述 反射機制是Java提供的一項比較高階的功能,一般的Java開發者使用它的時候相對比較少。但是,java的反射卻是大多數框架的基礎,例如,Struts,Hibernate,Spring等,反射機制就好像外科醫生的解剖工具,突然從外太空來了一個人,如何知道他的具體構造呢?最好的辦法

    java反射機制2- 實踐:反射機制+動態代理實現模擬RMI遠端方法呼叫

    1 涉及主要知識點   1、RMI(Remote Method Invocation):遠端方法呼叫是一種計算機之間利用遠端物件互相呼叫實現雙方通訊的一種通訊機制。使用這種機制,某一臺計算機上

    非深入探尋Java反射機制 Class

    Classes 通過反射機制我們可以在執行時探尋類的內部結構,並獲取以下資訊 Class NameClass Modifiers (public, protected, synchronized等)Package InfoSuper ClassImplemented In

    Java 反射基礎

    在上一篇部落格《 Java 反射基礎(上)》中,記錄瞭如何在執行時獲取類的所有變數和方法,還沒看的讀者可以看一下。 都知道,物件是無法訪問或操作類的私有變數和方法的,但是,通過反射,我們就可以做到!沒錯,反射可以做到!今天,將在上一次記錄的基礎上繼續探討如

    菜鳥學Java——Java反射機制

    上一篇博文《菜鳥學Java(九)——Java反射機制(一)》裡面,向大家介紹了什麼是Java的反射機制,以及Java的反射機制有什麼用。上一篇比較偏重理論,理論的東西給人講出來總感覺虛無縹緲,還是結合一些例項比較形象具體。那麼今天就結合更多的例項具體說說。 例項一:獲得

    Java 反射機制1

    一、準備知識: 1、什麼是 Java 反射機制? JAVA 反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射

    通俗易懂解釋java反射機制

    Java的反射機制是Java特性之一,反射機制是構建框架技術的基礎所在。靈活掌握Java反射機制,對大家以後學習框架技術有很大的幫助。  那麼什麼是Java的反射呢?        大家都知道,要讓Java程式能夠執行,那麼就得讓Java類要被Java虛擬機器載入。Java

    Java反射研究2

    接Java反射研究(1) 九、呼叫特定方法 Method m = c1.getMethod("funcname",Class<?>...c);   //funcname表示呼叫方法的名稱,c表示引數的Class物件 例如:Method m = c1.getM

    Java中的反射機制

    erl void port 令行 sage [0 ray 輸出 我們 基本概念   在Java運行時環境中,對於任意一個類,能否知道這個類有哪些屬性和方法?對於任意一個對象,能否調用它的任意一個方法?   答案是肯定的。   這種動態獲取類的信息以及動態調用對象的方法的功能

    java反射機制重要

    ati 接收 模式 stack 判斷 try per image declare 1,反射的概念 JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法

    Java動態性之反射機制reflection

    clas nts 一次 完全 名稱 set 靜態類 對象實例 以及 說到反射機制,第一次接觸的人可能會比較懵,反射?什麽反射?怎麽反射?反射是幹嘛的?下面我將在這篇文章中講講Java的反射機制 不過在這之前,還有一個問題需要解決,標題名中的動態性,說起動態性,我先介紹介紹動

    java中異常Exception的定義,意義和用法。舉例

    use 詳情 put 視頻下載 ati itl url index ring 1.異常(Exception)的定義,意義和用法 (視頻下載) (全部書籍) 我們先給出一個例子,看看異常有什麽用? 例:1.1-本章源碼 public class Test { publi

    Java架構技術——思路導圖

          做技術的就是話不多,技術人看圖就明白。  思路導圖如下: 歡迎工作一到五年的Java工程師朋友們加入Java架構群:897889510群內提供免費的Java架構學習資料(裡面有高可用、高併發、高效能及分散式、Jvm效能調優、Sprin

    實現ApplicationContextAware介面,javanew或者java反射獲取的物件中獲取spring容器的bean

    本文參考了https://blog.csdn.net/bailinbbc/article/details/76446594,其實是拷貝了很多內容: 在Web應用中,Spring容器通常採用宣告式方式配置產生:開發者只要在web.xml中配置一個Listener,該Listener將會負責初始化S

    java 8的新特性

    Lambda表示式–允許把函式作為一個方法的引數傳遞進去; 方法引用--可以直接引用已有Java類或者物件(例項)的方法或者構造器。與lambda聯合使用,方法引用可以使語言的構造更緊湊簡潔,減少冗餘程式碼。 函式式介面–函式式介面(FunctionalInterface)就是一個有

    Java反射機制超詳細

    文章目錄 反射機制是什麼 反射機制能做什麼 案例 通過一個物件獲得完整的包名和類名 例項化Class類物件 獲取一個物件的父類與實現的介面 通過反射機制例項化一個類的物件 獲取某個類的全部屬性 獲得某個