java 反射

一:
java.lang.Class
類:Class是一個類,構造方法是private,由JVM建立(沒法直接new CLass(),其對象是內存裏的一份字節碼)。
放射: 反射是java語言的一個特性,它允程序在運行時(注意不是編譯的時候)來進行自我檢查而且對內部的成員進行操做。
例如它容許一個java的類獲取他全部的成員變量和方法而且顯示出來。
Java 的這一能力在實際應用中也許用得不是不少,可是在其它的程序設計語言中根本就不存在這一特性。
例如,Pascal、C 或者 C++ 中就沒有辦法在程序中得到函數定義相關的信息。
reflection能夠動態的載入並取得 Java 組件(類) 的屬性。(來自Sun)

 Class 類的實例表示正在運行的 Java 應用程序中的類和接口。枚舉是一種類,註釋是一種接口。每一個數組屬於被映射爲 Class 對象的一個類,全部具備相同元素類型和維數的數組都共享該 Class 對象。java

基本的 Java類型(boolean、byte、char、short、int、long、float 和 double)和關鍵字 void 也表示爲 Class 對象。Class 沒有公共構造方法。數組

 

如何獲得類的信息: Class 對象是在加載類時由 Java 虛擬機以及經過調用類加載器中的 defineClass 方法自動構造的。以下,三種方法能夠獲得類的信息:函數

能夠經過類名稱(Date.class);能夠經過對象獲得(p1.getclass);也能夠經過一個運行時的字符串(Class.forname("XXXXX"))獲得。spa

     Person p1 = new Person();
        //下面的這三種方式均可以獲得字節碼
        Class c1 = Date.class;
        Class<? extends Person> c2 = p1.getClass();
        Class<?> c3 = null;
        //若存在則加載,不然新建,每每使用第三種,類的名字在寫源程序時不須要知道,到運行時再傳遞過來
        try {
           c3 = Class.forName("java.lang.String");
// forName中的參數必定是完整的類名(包名+類名),而且這個方法須要捕獲異常 }
catch (ClassNotFoundException e) { e.printStackTrace(); }

 下面有一個例子:設計

 Class c = null;
        try {
            c = Class.forName("reflection.Person");
            Method m[] = c.getDeclaredMethods();

            for (int i = 0; i < m.length; i++) {
                System.out.println(m[i].toString());
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

輸出:以下,輸出類的各方法名,以及它們的限制符,和返回類型和參數code

public void reflection.Person.setName(java.lang.String)
public void reflection.Person.setAge(int)
public int reflection.Person.getAge()
private java.lang.String reflection.Person.func(java.lang.String)對象

 

例2: 以下利用Class的newInstance方法至關於調用類的默認的構造器。若是類沒有無參的構造器,就會拋出異常。blog

  Person  p = new Person(5, "");

        Class<? extends Person> c = p.getClass();

        try {
            Person da = c.newInstance();   
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

 二:經常使用方法繼承

1 isPrimitive(判斷是不是基本類型的字節碼)
2 java中構造方法沒有前後順序,經過類型和參數個數區分。

        java中構造方法沒有前後順序,經過類型和參數個數區分接口

        try {
            Constructor<Person> con1 = Person.class.getConstructor(int.class, String.class);
            Constructor<Person> con2 = Person.class.getConstructor();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

   3 Filed類表明某一類中的一個成員變量。

Field[] f = Person.class.getFields();           // 只能獲得public的
Field f1 = Person.class.getField("age");     // 只能獲得public的
Field[] f2 = Person.class.getDeclaredFields();   //  各類可見性的均可以獲得,可是繼承的得不到
Field f3 = Person.class.getDeclaredField("age");   //各類可見性的均可以獲得,可是繼承的得不到
Person p = new Person(5, "jack");
Field f3 = Person.class.getDeclaredField("age");
f3.setAccessible(true); // 若是是私有的屬性, 必定要臨時改其屬性
String rs = (String) f3.get(p);

 4:  給定一個類的全名,調用main方法:

       Method m = Class.forName(str).getMethod("main",String[].class);
      
        m.invoke(null, new Object[]{new String[]{"111","222","333"}});
        m.invoke(null, (Object)new String[]{"111","222","333"});//這個能夠說明,數組也是Object

5: 模擬instanceof 操做

 Person p = new Person(5, "jack");
Person.class.isInstance(p);
 
三:Method類
    try {
            String str = "shfsfs";
            //包開頭是com表示是sun內部用的,java打頭的纔是用戶的
            Method mtCharAt = String.class.getMethod("charAt", int.class);
            Object ch = mtCharAt.invoke(str, 1);//若第一個參數是null,則確定是靜態方法
            System.out.println(ch);

            System.out.println(mtCharAt.invoke(str, new Object[] {2}));//1.4語法
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
相關文章
相關標籤/搜索