Java反射(完結(jié))

參考文章:
http://www.reibang.com/p/607ff4e79a13
https://juejin.im/post/6844903776873086989#heading-32
練習(xí)源碼

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;

/**
 * Member
 * java.lang.reflect.Field :對應(yīng)類變量
 * java.lang.reflect.Method :對應(yīng)類方法
 * java.lang.reflect.Constructor :對應(yīng)類構(gòu)造函數(shù)
 *
 *
 * AccessibleObject
 * java.lang.reflect.Method :成員方法,靜態(tài)方法
 * java.lang.reflect.Constructor :構(gòu)造方法
 */
public class TestReflect {

    public static void main(String[] args) {
        Class c = null;
        Object obj = null;
        try {
            c = Class.forName("com.example.wifi.Reflect.Cat");
            obj = c.getConstructor(String.class, int.class).newInstance("短歌短歌", 1);

            /**
             * 1,屬性:變量,靜態(tài)變量,靜態(tài)常量
             * getDeclaredField(String name)
             * 獲取指定的變量(只要是聲明的變量都能獲得舀透,包括private)
             * getField(String name)
             * 獲取指定的變量(只能獲得public的)
             * getDeclaredFields()
             * 獲取所有聲明的變量(包括private)
             * getFields()
             * 獲取所有的public變量
             */
            //name
            Field fieldName = c.getDeclaredField("name");
            fieldName.setAccessible(true);//可以訪問private修改的變量
            String name = (String) fieldName.get(obj);
            System.out.println("name : " + name);
            fieldName.set(obj, "富力東方");
            String name2 = (String) fieldName.get(obj);
            System.out.println("name : " + name2);
            //TAG1
            Field fieldTAG1 = c.getDeclaredField("TAG1");
            fieldTAG1.setAccessible(true);
            String TAG1 = (String) fieldTAG1.get(null);
            System.out.println("TAG1 : " + TAG1);
            //TAG2
            Field fieldTAG2 = c.getDeclaredField("TAG2");
            fieldTAG2.setAccessible(true);
            String TAG2 = (String) fieldTAG2.get(obj);
            System.out.println("TAG2 : " + TAG2);


            /**
             * 2,Method
             * getDeclaredMethod(String name, Class<?>... parameterTypes)
             * 根據(jù)方法名獲得指定的方法切厘, 參數(shù)name為方法名奈懒,參數(shù)parameterTypes為方法的參數(shù)類型浪汪,如 getDeclaredMethod(“eat”, String.class)
             * getMethod(String name, Class<?>... parameterTypes)
             * 根據(jù)方法名獲取指定的public方法,其它同上
             * getDeclaredMethods()
             * 獲取所有聲明的方法
             * getMethods()
             * 獲取所有的public方法
             */
            //靜態(tài)方法
            Method methodGetTAG = c.getDeclaredMethod("getTAG");
            methodGetTAG.setAccessible(true);
            String result = (String) methodGetTAG.invoke(null);
            System.out.println("getTAG : " + result);
            //成員方法
            Method methodSetName = c.getDeclaredMethod("setName", String.class);
            methodSetName.invoke(obj, "猜猜我是誰");
            Method methodGetName = c.getDeclaredMethod("getName");
            String getName = (String) methodGetName.invoke(obj);
            System.out.println("getName : " + getName);
            //3,獲取方法的返回值的class和taype
            Class classReturnType = methodGetName.getReturnType();
            Type getGenericReturnType = methodGetName.getGenericReturnType();

            //方法參數(shù)的class和type的數(shù)組.
            Class[] getDeclaringClass = methodSetName.getParameterTypes();
            Type[] getParameterTypes = methodSetName.getGenericParameterTypes();

            //獲取方法參數(shù)相關(guān)信息
            Parameter[] getParameters = methodSetName.getParameters();
            for (int i = 0; i < getParameters.length; i++) {
                Parameter p = getParameters[i];
                p.getType();   //獲取參數(shù)類型
                p.getName();  //獲取參數(shù)名稱窿祥,如果編譯時未加上`-parameters`,返回的名稱形如`argX`, X為參數(shù)在方法聲明中的位置,從0開始
                p.getModifiers(); //獲取參數(shù)修飾符
                p.isNamePresent();  //.class文件中是否保存參數(shù)名稱, 編譯時加上`-parameters`返回true,反之flase
            }
            System.out.println("是否是可變參數(shù)"+methodSetName.isVarArgs()); //判斷方法參數(shù)是否是可變參數(shù)
            System.out.println("是否是復(fù)合方法"+methodSetName.isSynthetic()); //判斷是否是復(fù)合方法放典,個人理解復(fù)合方法是編譯期間編譯器生成的方法,并不是源代碼中有的方法
            System.out.println("是否是橋接方法"+methodSetName.isBridge());  //判斷是否是橋接方法基茵,橋接方法是 JDK 1.5 引入泛型后奋构,為了使Java的泛型方法生成的字節(jié)碼和 1.5 版本前的字節(jié)碼相兼容,由編譯器自動生成的方法拱层∶志剩可以參考


            //調(diào)用定項參數(shù)方法
            Method eat = c.getDeclaredMethod("eat", String.class);
            eat.invoke(obj, "grass");
            //調(diào)用不定項參數(shù)方法
            //不定項參數(shù)可以當成數(shù)組來處理
            Class[] argTypes = new Class[] { String[].class };
            Method varargsEat = c.getDeclaredMethod("eat", argTypes);
            String[] foods = new String[]{
                    "grass", "meat","蘋果","白菜"
            };
            varargsEat.invoke(obj, (Object)foods);


            /**
             * 3,構(gòu)造方法
             * getDeclaredConstructor(Class<?>... parameterTypes)
             * 獲取指定構(gòu)造函數(shù),參數(shù)parameterTypes為構(gòu)造方法的參數(shù)類型
             * getConstructor(Class<?>... parameterTypes)
             * 獲取指定public構(gòu)造函數(shù)根灯,參數(shù)parameterTypes為構(gòu)造方法的參數(shù)類型
             * getDeclaredConstructors()
             * 獲取所有聲明的構(gòu)造方法
             * getConstructors()
             * 獲取所有的public構(gòu)造方法
             */
            Constructor constructor = c.getDeclaredConstructor(String.class);//獲取私有構(gòu)造方法
            constructor.setAccessible(true);
            Animal cat = (Cat) constructor.newInstance("只有一個");
            System.out.println("獲取名字"+cat.toString());

            /**
             * 4,數(shù)組
             */

            Field field = c.getDeclaredField("arryInt");
            field.setAccessible(true);
            //獲取一個變量的類型
            Class<?> cArray = field.getType();
            //判斷該變量是否為數(shù)組
            if (cArray.isArray()) {
                //獲取數(shù)組的元素類型
                int[] array = (int[]) field.get(obj);
                for (int i = 0; i < array.length; i++) {
                    System.out.println(Array.get(array, i));//讀取下標bai2數(shù)組du元素zhi
                }
            }

            /**
             * 5,枚舉
             */
            Class classEnum = Class.forName("com.example.wifi.Reflect.StatuEnum");
            if (classEnum.isEnum()) {
                Object[] objectEnum = classEnum.getEnumConstants();
                for (int i = 0; i < objectEnum.length; i++) {
                    System.out.println("枚舉="+objectEnum[i]);
                    System.out.println("枚舉值="+((StatuEnum)objectEnum[i]).s);
                }
            }


        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}


//父類
public class Animal {
    private String name;
    private int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Animal : name = " + name + " age = " + age;
    }
}


//反射獲取的對象類
import java.io.Serializable;
class Cat extends Animal implements Serializable {
    private static final String TAG = Cat.class.getSimpleName();

    private static String TAG1 = Cat.class.getName();

    private final String TAG2 = "lalala";

    private int[] arryInt = {1, 2, 3, 4, 5, 6};

    private String name;

    private int i = new Integer(10);

    @Deprecated
    public int age;

    public Cat() {
        super("", 0);
    }

    private Cat(String name) {
        super(name, 0);
        this.name = name;
    }

    public Cat(String name, int age) {
        super(name, age);
        this.name = name;
        this.age = age;
    }

    public void setName(String names) {
        this.name = names;
    }

    public String getName() {
        return name;
    }

    public void eat(String food) {
        System.out.println(TAG + "eat food " + food);
    }

    public void eat(String... foods) {
        StringBuilder s = new StringBuilder();
        for (String food : foods) {
            s.append(food);
            s.append(" ");
        }
        System.out.println(TAG + "eat food " + s.toString());
    }

    public void sleep() {
        System.out.println(TAG + "sleep");
    }


    private static  String getTAG() {
        return TAG;
    }

    @Override
    public String toString() {
        return "name = " + name + " age = " + age;
    }
}

//枚舉
public enum StatuEnum {
    START("start"), STOP("stop"), DESTROY("destroy");

    StatuEnum(String s) {
        this.s = s;
    }

    String s;
}



?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末径缅,一起剝皮案震驚了整個濱河市掺栅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纳猪,老刑警劉巖氧卧,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異氏堤,居然都是意外死亡沙绝,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門鼠锈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闪檬,“玉大人,你說我怎么就攤上這事购笆〈置酰” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵由桌,是天一觀的道長为黎。 經(jīng)常有香客問我,道長行您,這世上最難降的妖魔是什么铭乾? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮娃循,結(jié)果婚禮上炕檩,老公的妹妹穿的比我還像新娘。我一直安慰自己捌斧,他們只是感情好笛质,可當我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捞蚂,像睡著了一般妇押。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上姓迅,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天敲霍,我揣著相機與錄音,去河邊找鬼丁存。 笑死肩杈,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的解寝。 我是一名探鬼主播扩然,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼聋伦!你這毒婦竟也來了夫偶?” 一聲冷哼從身側(cè)響起界睁,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎索守,沒想到半個月后晕窑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡卵佛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年杨赤,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片截汪。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡疾牲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出衙解,到底是詐尸還是另有隱情阳柔,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布蚓峦,位于F島的核電站舌剂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏暑椰。R本人自食惡果不足惜霍转,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望一汽。 院中可真熱鬧避消,春花似錦、人聲如沸召夹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽监憎。三九已至纱意,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鲸阔,已是汗流浹背偷霉。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留隶债,地道東北人腾它。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓跑筝,卻偏偏與公主長得像死讹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子曲梗,可洞房花燭夜當晚...
    茶點故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容

  • 類加載機制 1 什么是反射 Java反射機制是在運行狀態(tài)中對于任意一個類赞警,都能知道這個類的所以屬性和方法妓忍;對于任何...
    凱玲之戀閱讀 13,838評論 3 28
  • 前言 當你興沖沖地開始運行自己的Java項目時,你是否遇到過如下問題: 程序在穩(wěn)定運行了愧旦,可是實現(xiàn)的功能點了沒反應(yīng)...
    蠻三刀醬閱讀 2,227評論 0 14
  • 序言 最近正在重新系統(tǒng)的學(xué)習(xí)iOS世剖,收集了一些自己認為不錯的博客和資料和大家分享。有??標記的是我看過覺得詳細易懂...
    等消息的人閱讀 2,997評論 0 47
  • 久違的晴天笤虫,家長會旁瘫。 家長大會開好到教室時,離放學(xué)已經(jīng)沒多少時間了琼蚯。班主任說已經(jīng)安排了三個家長分享經(jīng)驗酬凳。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,523評論 16 22
  • 創(chuàng)業(yè)是很多人的夢想,多少人為了理想和不甘選擇了創(chuàng)業(yè)來實現(xiàn)自我價值遭庶,我就是其中一個宁仔。 創(chuàng)業(yè)后,我由女人變成了超人峦睡,什...
    亦寶寶閱讀 1,812評論 4 1