溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java框架設(shè)計之反射怎么應(yīng)用

發(fā)布時間:2022-06-22 09:40:44 來源:億速云 閱讀:132 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“Java框架設(shè)計之反射怎么應(yīng)用”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Java框架設(shè)計之反射怎么應(yīng)用”吧!

    框架:半成品軟件??梢栽诳蚣艿幕A(chǔ)上進(jìn)行軟件開發(fā),簡化編碼。

    反射就是把Java類中的各個成員映射成一個個的Java對象。

    即在運(yùn)行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;

    對于任意一個對象,都能調(diào)用它的任意一個方法和屬性。

    這種動態(tài)獲取信息及動態(tài)調(diào)用對象方法的功能叫Java的反射機(jī)制。

    好處:

    1. 可以在程序運(yùn)行過程中,操作這些對象。

    2. 可以解耦,提高程序的可擴(kuò)展性。

    獲取Class對象的方式

    1. Class.forName("全類名"):將字節(jié)碼文件加載進(jìn)內(nèi)存,返回Class對象

    多用于配置文件,將類名定義在配置文件中。讀取文件,加載類。

    2. 類名.class:通過類名的屬性class獲取

    多用于參數(shù)的傳遞

    3. 對象.getClass():getClass()方法在Object類中定義著。

    多用于對象的獲取字節(jié)碼的方式

    //1.Class.forName("全類名")
    Class cls1 = Class.forName("com.zjq.javabase.base25.domain.Person");
    System.out.println(cls1);
    //2.類名.class
    Class cls2 = Person.class;
    System.out.println(cls2);
    //3.對象.getClass()
    Person p = new Person();
    Class cls3 = p.getClass();
    System.out.println(cls3);

    結(jié)論:

    同一個字節(jié)碼文件(*.class)在一次程序運(yùn)行過程中,只會被加載一次,不論通過哪一種方式獲取的Class對象都是同一個。

    Class對象功能

    測試的Person類:

    package com.zjq.javabase.base25.domain;
     
    /**
     * @author zjq
     */
    public class Person {
        private String name;
        private int age;
     
        public String a;
        protected String b;
        String c;
        private String d;
     
     
        public Person() {
        }
     
        public Person(String name, int age) {
     
            this.name = name;
            this.age = age;
        }
     
        public String getName() {
            return name;
        }
     
        public void setName(String name) {
            this.name = name;
        }
     
        public int getAge() {
            return age;
        }
     
        public void setAge(int age) {
            this.age = age;
        }
     
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", a='" + a + '\'' +
                    ", b='" + b + '\'' +
                    ", c='" + c + '\'' +
                    ", d='" + d + '\'' +
                    '}';
        }
     
     
        public void eat(){
            System.out.println("eat...");
        }
     
        public void eat(String food){
            System.out.println("eat..."+food);
        }
    }

    獲取成員變量們

    Field[] getFields() :獲取所有public修飾的成員變量

    Field getField(String name)   獲取指定名稱的 public修飾的成員變量

    Field[] getDeclaredFields()  獲取所有的成員變量,不考慮權(quán)限修飾符

    Field getDeclaredField(String name)  

    案例:

    //0.獲取Person的Class對象
    Class personClass = Person.class;
    //1.Field[] getFields()獲取所有public修飾的成員變量
    Field[] fields = personClass.getFields();
    for (Field field : fields) {
        System.out.println(field);
    }
     
    System.out.println("------------");
    //2.Field getField(String name)
    Field a = personClass.getField("a");
    //獲取成員變量a 的值
    Person p = new Person();
    Object value = a.get(p);
    System.out.println(value);
    //設(shè)置a的值
    a.set(p,"張三");
    System.out.println(p);
     
    System.out.println("===================");
     
    //Field[] getDeclaredFields():獲取所有的成員變量,不考慮修飾符
    Field[] declaredFields = personClass.getDeclaredFields();
    for (Field declaredField : declaredFields) {
        System.out.println(declaredField);
    }
    //Field getDeclaredField(String name)
    Field d = personClass.getDeclaredField("d");
    //忽略訪問權(quán)限修飾符的安全檢查
    d.setAccessible(true);//暴力反射
    Object value2 = d.get(p);
    System.out.println(value2);

    獲取構(gòu)造方法們

    Constructor<?>[] getConstructors()  

    Constructor<T> getConstructor(類<?>... parameterTypes)  

    Constructor<T> getDeclaredConstructor(類<?>... parameterTypes)  

    Constructor<?>[] getDeclaredConstructors()  

    案例:

    //0.獲取Person的Class對象
    Class personClass = Person.class;
     
    //Constructor<T> getConstructor(類<?>... parameterTypes)
    Constructor constructor = personClass.getConstructor(String.class, int.class);
    System.out.println(constructor);
    //創(chuàng)建對象
    Object person = constructor.newInstance("張三", 23);
    System.out.println(person);
     
    System.out.println("----------");
     
     
    Constructor constructor1 = personClass.getConstructor();
    System.out.println(constructor1);
    //創(chuàng)建對象
    Object person1 = constructor1.newInstance();
    System.out.println(person1);
     
    Object o = personClass.newInstance();
    System.out.println(o);

    獲取成員方法們

    Method[] getMethods()  

    Method getMethod(String name, 類<?>... parameterTypes)  

    Method[] getDeclaredMethods()  

    Method getDeclaredMethod(String name, 類<?>... parameterTypes)  

    案例:

    //0.獲取Person的Class對象
    Class personClass = Person.class;
    //獲取指定名稱的方法
    Method eat_method = personClass.getMethod("eat");
    Person p = new Person();
    //執(zhí)行方法
    eat_method.invoke(p);
     
     
    Method eat_method2 = personClass.getMethod("eat", String.class);
    //執(zhí)行方法
    eat_method2.invoke(p,"飯");
     
    System.out.println("-----------------");
     
    //獲取所有public修飾的方法
    Method[] methods = personClass.getMethods();
    for (Method method : methods) {
        System.out.println(method);
        String name = method.getName();
        System.out.println(name);
        //method.setAccessible(true);
    }
     
    //獲取類名
    String className = personClass.getName();
    System.out.println(className);//com.zjq.javabase.base25.domain.Person

    獲取全類名  

    String getName()  

    Field:成員變量

    操作:

    1. 設(shè)置值

    void set(Object obj, Object value)  

    2. 獲取值

    get(Object obj) 

    3. 忽略訪問權(quán)限修飾符的安全檢查

    setAccessible(true):暴力反射

    Constructor:構(gòu)造方法

    創(chuàng)建對象:

    T newInstance(Object... initargs)  

    如果使用空參數(shù)構(gòu)造方法創(chuàng)建對象,操作可以簡化:Class對象的newInstance方法

    Method:方法對象

    執(zhí)行方法:

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

    獲取方法名稱:

    String getName:獲取方法名

    案例

    需求:寫一個"框架",不能改變該類的任何代碼的前提下,可以幫我們創(chuàng)建任意類的對象,并且執(zhí)行其中任意方法

    實(shí)現(xiàn):

    1. 配置文件

    2. 反射

    步驟:

    1. 將需要創(chuàng)建的對象的全類名和需要執(zhí)行的方法定義在配置文件中

    2. 在程序中加載讀取配置文件

    3. 使用反射技術(shù)來加載類文件進(jìn)內(nèi)存

    4. 創(chuàng)建對象

    5. 執(zhí)行方法

    代碼:

    pro.properties文件內(nèi)容如下:

    className=com.zjq.javabase.base25.domain.Student
    methodName=sleep

    Student類:

    public class Student {
     
        public void sleep() {
            System.out.println("sleep...");
        }
    }

    反射操作:

    //1.加載配置文件
    //1.1創(chuàng)建Properties對象
    Properties pro = new Properties();
    //1.2加載配置文件,轉(zhuǎn)換為一個集合
    //1.2.1獲取class目錄下的配置文件
    ClassLoader classLoader = ReflectTest.class.getClassLoader();
    InputStream is = classLoader.getResourceAsStream("pro.properties");
    pro.load(is);
     
    //2.獲取配置文件中定義的數(shù)據(jù)
    String className = pro.getProperty("className");
    String methodName = pro.getProperty("methodName");
     
     
    //3.加載該類進(jìn)內(nèi)存
    Class cls = Class.forName(className);
    //4.創(chuàng)建對象
    Object obj = cls.newInstance();
    //5.獲取方法對象
    Method method = cls.getMethod(methodName);
    //6.執(zhí)行方法
    method.invoke(obj);

    感謝各位的閱讀,以上就是“Java框架設(shè)計之反射怎么應(yīng)用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Java框架設(shè)計之反射怎么應(yīng)用這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI