中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

Java內省機制怎么實現

發布時間:2022-08-08 11:06:48 來源:億速云 閱讀:139 作者:iii 欄目:開發技術

本篇內容主要講解“Java內省機制怎么實現”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java內省機制怎么實現”吧!

    概念

    JavaBean

    在實際編程中,我們常常需要一些用來包裝值對象的類,例如Student、 Employee、Order,這些 類中往往沒有業務方法,只是為了把需要處理的實體對象進行封裝,有這樣的特征:

    • 屬性都是私有的;

    • 有無參的public構造方法;

    • 對私有屬性根據需要提供公有的getXxx方法以及setXxx方法;

    比如:屬性名稱為name,則有getName方法返回屬性name值, setName方法設置name值;注意方法的名稱通常是get或 set加上屬性名稱,并把屬性名稱的首字母大寫;這些方法稱為getters/setters;getters必須有返回值沒有方法參數; setter值沒有返回值,有方法參數;

    例如下面的例子:

    Java內省機制怎么實現

    符合這些特征的類,被稱為JavaBean;

    內省

    內省(Inspector)機制就是基于反射的基礎, Java語言對Bean類屬性、事件的一種缺省處理方法。

    只要類中有getXXX方法,或者setXXX方法,或者同時有getXXX及setXXX方法,其中getXXX方 法沒有方法參數,有返回值; setXXX方法沒有返回值,有一個方法參數;那么內省機制就認為 XXX為一個屬性;

    例如下面代碼

    Employee類中根本沒有聲明age屬性,僅僅是聲明了這樣的getter和setter.內省機制就認為age是屬性

    package com.shixun.introspector;
    
    public class Employee {
        private String name;
        private Double score;
    
        // age將被內省認為是屬性
        public int getAge(){
            return 30;
        }
    
        // name將被內省認為是屬性
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        // score將被內省認為是屬性
        public Double getScore() {
            return score;
        }
    
        public void setScore(Double score) {
            this.score = score;
        }
    
        public static void main(String[] args) {
            
    
        }
    }

    相關API

    與Java內省有關的主要類及接口有:

    • java.beans.Introspector類: 為獲得JavaBean屬性、事件、方法提供了標準方法;通常使用其中的getBeanInfo方法返回BeanInfo對象;

    • Java.beans.BeanInfo接口:不能直接實例化,通常通過Introspector類返回該類型對象,提供了返回屬性描述符對象(PropertyDescriptor)、方法描述符對象(MethodDescriptor) 、 bean描述符(BeanDescriptor)對象的方法;

    • Java.beans.PropertyDescriptor類:用來描述一個屬性,該屬性有getter及setter方法;

    可以使用PropertyDescriptor類的方法獲取屬性相關的信息,例如getName方法返回屬性的名字:

    PropertyDescriptor類中定義了方法可以獲取該屬性的getter和setter方法

    方法方法描述
    Method getReadMethod()回屬性對應的getter方法對象;
    Method getWriteMethod()回屬性對應的setter方法對象;

    下面我們來用代碼深入探究一下:

    代碼案例:獲取屬性相關信息

    Employee如上面代碼所示,繼續編寫主函數進行測試

    首先用BeanInfo接口獲取BeanInfo的對象,再通過BeanInfo對象獲取PropertyDescriptor屬性描述

     //獲取BeanInfo的對象
     BeanInfo employeeBeanInfo = Introspector.getBeanInfo(Employee.class);
     //通過BeanInfo對象獲取PropertyDescriptor屬性描述
     PropertyDescriptor[] propertyDescriptors = employeeBeanInfo.getPropertyDescriptors();
     System.out.println("通過Inspector內省機制獲取JavaBean屬性======= 打印所有信息 ====================");
     Arrays.stream(propertyDescriptors).forEach(f->{
         System.out.println("====================================");
         System.out.println("屬性名:"+f.getName());
         System.out.println("類型:"+f.getPropertyType());
         System.out.println("get方法:"+f.getReadMethod());
         System.out.println("set方法:"+f.getWriteMethod());
     });
    
    // 或者用增強for
    System.out.println("通過Inspector內省機制獲取JavaBean屬性======= 打印所有信息 ====================");
    for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
    	System.out.println("====================================");
        System.out.println("名字:" + propertyDescriptor.getName());
        System.out.println("類型:" + propertyDescriptor.getPropertyType());
        System.out.println("get方法:" + propertyDescriptor.getReadMethod());
        System.out.println("set方法:" + propertyDescriptor.getWriteMethod());
    }

    運行結果如下:

    Java內省機制怎么實現

    我們也可以通過反射調用這里獲取的get或set方法

    //創建Employee的對象
    Class<?> clazz = Class.forName("com.shixun.introspector.Employee");
    Object employee = clazz.newInstance();
    
    //遍歷屬性描述對象
    for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
        //打印屬性名稱
        System.out.println(propertyDescriptor.getName());
        //判斷屬性名稱是不是name
        if (propertyDescriptor.getName().equals("name")) {
            //setter方法
            Method writeMethod = propertyDescriptor.getWriteMethod();
            //調用setName方法
            writeMethod.invoke(employee, "jack");
            //getter方法
            Method readMethod = propertyDescriptor.getReadMethod();
            //調用getName方法
            Object nameValue = readMethod.invoke(employee);
            System.out.println("name屬性的值為:" + nameValue);
        }
        //判斷屬性名稱是否為score
        if (propertyDescriptor.getName().equals("score")) {
            //setter方法
            Method scoreWriteMethod = propertyDescriptor.getWriteMethod();
            //調用setScore方法
            scoreWriteMethod.invoke(employee, new Double(3000));
            //getter方法
            Method scoreReadMethod = propertyDescriptor.getReadMethod();
            Object scoreValue = scoreReadMethod.invoke(employee);
            System.out.println("score屬性的值為:" + scoreValue);
        }
    }
    System.out.println("當前對象的信息:"+employee.toString());

    運行結果如下所示:

    Java內省機制怎么實現

    全部代碼附在最下方!!!!!!

    內省屬性的注意事項

    • 很多框架都使用了內省機制檢索對象的屬性,定義屬性名字時,名字最好起碼以兩個小寫字母開頭,例如stuName,而不要使用sName,某些情況下,可能會導致檢索屬性失敗;

    • 內省機制檢索屬性時,是根據getter和setter方法確認屬性名字,而不是根據類里聲明的成員變量名稱決定;

    完整代碼

    package com.shixun.introspector;
    
    import java.beans.BeanInfo;
    import java.beans.IntrospectionException;
    import java.beans.Introspector;
    import java.beans.PropertyDescriptor;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Arrays;
    
    public class Employee {
        private String name;
        private Double score;
    
        // age將被內省認為是屬性
        public int getAge() {
            return 30;
        }
    
        // name將被內省認為是屬性
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        // score將被內省認為是屬性
        public Double getScore() {
            return score;
        }
    
        public void setScore(Double score) {
            this.score = score;
        }
    
        @Override
        public String toString() {
            return "Employee{" +
                    "name='" + name + '\'' +
                    ", score=" + score +
                    '}';
        }
    
        public static void main(String[] args) throws ClassNotFoundException, IntrospectionException, IllegalAccessException, InstantiationException, InvocationTargetException {
            //獲取BeanInfo的對象
            BeanInfo employeeBeanInfo = Introspector.getBeanInfo(Employee.class);
    
            //通過BeanInfo對象獲取PropertyDescriptor屬性描述
            PropertyDescriptor[] propertyDescriptors = employeeBeanInfo.getPropertyDescriptors();
    //        System.out.println("通過Inspector內省機制獲取JavaBean屬性======= 打印所有信息 ====================");
    //        Arrays.stream(propertyDescriptors).forEach(f->{
    //            System.out.println("====================================");
    //            System.out.println("屬性名:"+f.getName());
    //            System.out.println("類型:"+f.getPropertyType());
    //            System.out.println("get方法:"+f.getReadMethod());
    //            System.out.println("set方法:"+f.getWriteMethod());
    //        });
    //
    //
    //
    //        System.out.println("通過Inspector內省機制獲取JavaBean屬性======= 打印所有信息 ====================");
    //
    //        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
    //            System.out.println("名字:" + propertyDescriptor.getName());
    //            System.out.println("類型:" + propertyDescriptor.getPropertyType());
    //            System.out.println("get方法:" + propertyDescriptor.getReadMethod());
    //            System.out.println("set方法:" + propertyDescriptor.getWriteMethod());
    //        }
    
            //創建Employee的對象
            Class<?> clazz = Class.forName("com.shixun.introspector.Employee");
            Object employee = clazz.newInstance();
    
            //遍歷屬性描述對象
            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                //打印屬性名稱
                System.out.println(propertyDescriptor.getName());
                //判斷屬性名稱是不是name
                if (propertyDescriptor.getName().equals("name")) {
                    //setter方法
                    Method writeMethod = propertyDescriptor.getWriteMethod();
                    //調用setName方法
                    writeMethod.invoke(employee, "jack");
                    //getter方法
                    Method readMethod = propertyDescriptor.getReadMethod();
                    //調用getName方法
                    Object nameValue = readMethod.invoke(employee);
                    System.out.println("name屬性的值為:" + nameValue);
                }
                //判斷屬性名稱是否為score
                if (propertyDescriptor.getName().equals("score")) {
                    //setter方法
                    Method scoreWriteMethod = propertyDescriptor.getWriteMethod();
                    //調用setScore方法
                    scoreWriteMethod.invoke(employee, new Double(3000));
                    //getter方法
                    Method scoreReadMethod = propertyDescriptor.getReadMethod();
                    Object scoreValue = scoreReadMethod.invoke(employee);
                    System.out.println("score屬性的值為:" + scoreValue);
                }
            }
    
            System.out.println("當前對象的信息:"+employee.toString());
        }
    }

    到此,相信大家對“Java內省機制怎么實現”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    文安县| 江阴市| 浦城县| 通榆县| 上思县| 福鼎市| 鱼台县| 沂南县| 石首市| 乌兰浩特市| 宁阳县| 隆子县| 呼玛县| 惠东县| 大洼县| 汽车| 永城市| 望都县| 虹口区| 宣城市| 厦门市| 浙江省| 绥芬河市| 菏泽市| 胶南市| 集贤县| 孝义市| 德令哈市| 大荔县| 华容县| 通河县| 皋兰县| 秭归县| 东海县| 景宁| 饶平县| 娱乐| 钦州市| 志丹县| 南康市| 武冈市|