自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

比反射更好用的內(nèi)省,你知道嗎?

開發(fā) 前端
內(nèi)省機制通過反射獲取屬性描述器(PropertyDescriptor),然后可以方便地獲取和設(shè)置屬性值。內(nèi)省操作只針對JavaBean,只有符合JavaBean規(guī)則的類的成員才可以采用內(nèi)省API進(jìn)行操作。

內(nèi)省是基于反射實現(xiàn)的,主要用于操作符合JavaBean規(guī)范的類。

JavaBean是一種特殊的Java類,通常用于封裝多個屬性為一個單一的對象。我們再復(fù)習(xí)下JavaBean規(guī)范:

  • 必須要有一個公共無參構(gòu)造;
  • Javabean類不應(yīng)有公共屬性,屬性都應(yīng)該是 private;
  • 為私有(private聲明)屬性提供符合命名規(guī)范的getter/setter方法;
  • 應(yīng)該要實現(xiàn)Serializeable接口(內(nèi)省并不強要求這一條);
  • javaBean類必須是一個公共類,將其訪問屬性設(shè)置為public。

內(nèi)省機制通過反射獲取屬性描述器(PropertyDescriptor),然后可以方便地獲取和設(shè)置屬性值。

內(nèi)省操作只針對JavaBean,只有符合JavaBean規(guī)則的類的成員才可以采用內(nèi)省API進(jìn)行操作。

內(nèi)省的核心類在java.beans包下,主要類如下:

java.beans包java.beans包

初識內(nèi)省

內(nèi)省就是轉(zhuǎn)為JavaBean準(zhǔn)備的,主要包括下面幾個類:

  1. Introspector類:這是內(nèi)省API的核心類,提供了獲取BeanInfo對象的方法,例如Introspector.getBeanInfo()方法。
  2. BeanInfo類:這個類包含了關(guān)于一個對象的所有Bean屬性信息,包括屬性的描述符(PropertyDescriptor)。
  3. PropertyDescriptor類:表示一個JavaBean屬性的信息,包括getter和setter方法。

以下是一個簡單的示例,我們首先獲取User的JavaBean信息BeanInfo,然后找到屬性描述符PropertyDescriptor列表。

首先定義一個JavaBean:

@Data
public static class User {
    private String username;
}

這里借助Lombok的@Data注解,生成標(biāo)準(zhǔn)JavaBean。

首先獲取BeanInfo實例:

final BeanInfo beanInfo = Introspector.getBeanInfo(User.class);

此時beanInfo中就可以獲取User類的所有定義:

  • 通過getMethodDescriptors()可以獲取方法描述;
  • 通過getPropertyDescriptors()可以獲取屬性描述;
  • 使用PropertyDescriptor可以生成指定屬性的描述;

少年,至此你已經(jīng)學(xué)會屠龍技,可以開始屠龍了。

來個小李子

小李子小李子

話說小李子年輕時候真帥,可惜歲月是把殺豬刀~~

咳咳,言歸正傳,我們用上面學(xué)到的直接開始:

final BeanInfo userBeanInfo = Introspector.getBeanInfo(User.class);
final User user = new User();

for (MethodDescriptor methodDescriptor : userBeanInfo.getMethodDescriptors()) {
    System.out.println("Method Name: " + methodDescriptor.getName());
    final ParameterDescriptor[] parameterDescriptors = methodDescriptor.getParameterDescriptors();
    if (parameterDescriptors == null) {
        continue;
    }
    for (ParameterDescriptor parameterDescriptor : parameterDescriptors) {
        System.out.println("Parameter Name: " + parameterDescriptor.getName());
        System.out.println("Parameter DisplayName: " + parameterDescriptor.getDisplayName());
    }
}

// 遍歷所有屬性描述符
for (PropertyDescriptor prop : userBeanInfo.getPropertyDescriptors()) {
    System.out.println("Property Name: " + prop.getName());

    // 獲取getter方法
    final Method readMethod = prop.getReadMethod();
    if (readMethod != null) {
        Object value = readMethod.invoke(user);
        System.out.println("Property Value: " + value);
    }

    if ("username".equals(prop.getName())) {
        // 獲取setter方法
        final Method writeMethod = prop.getWriteMethod();
        if (writeMethod != null) {
            Object value = writeMethod.invoke(user, "看山");
            System.out.println("Property Value: " + value);
        }
    }
}
System.out.println(user);

輸出結(jié)果是:

Method Name: getClass
Method Name: wait
Method Name: notifyAll
Method Name: notify
Method Name: wait
Method Name: getUsername
Method Name: hashCode
Method Name: setUsername
Method Name: wait
Method Name: equals
Method Name: toString
Property Name: class
Property Value: class cn.howardliu.tutorials.core.reflect.IntrospectorDemo$User
Property Name: username
Property Value: null
Property Value: null
IntrospectorDemo.User(username=看山)

我們可以看到,MethodDescriptor方法描述符包含了User類的所有方法,包括父類的方法。

如果不是JavaBean呢?

我們再看一下,如果User不符合規(guī)范呢?

public static class UserNoSetter {
    private String username;

    public void username(String username) {
        this.username = username;
    }

    @Override
    public String toString() {
        return "UserNoSetter{" +
                "username='" + username + '\'' +
                '}';
    }
}

我們再看看上面的結(jié)果:

Method Name: getClass
Method Name: wait
Method Name: notifyAll
Method Name: notify
Method Name: wait
Method Name: hashCode
Method Name: setUsername
Method Name: wait
Method Name: equals
Method Name: toString
Method Name: username
Property Name: class
Property Value: class cn.howardliu.tutorials.core.reflect.IntrospectorDemo$UserNoSetter
UserNoSetter{username='null'}

可以看到,方法除了自定義的username和setUsername,其他都是相同的,但是setUsername我們定義成了builder模式,所以內(nèi)省描述符也不認(rèn)識了。

責(zé)任編輯:武曉燕 來源: 看山的小屋
相關(guān)推薦

2025-01-20 00:00:00

反射Java語言

2023-12-12 08:41:01

2021-10-14 06:52:47

算法校驗碼結(jié)構(gòu)

2024-09-18 07:00:00

消息隊列中間件消息隊列

2022-09-29 15:32:58

云計算計算模式

2024-04-07 00:00:00

ESlint命令變量

2024-05-28 09:12:10

2022-03-10 08:25:27

JavaScrip變量作用域

2019-12-12 09:23:29

Hello World操作系統(tǒng)函數(shù)庫

2023-12-20 08:23:53

NIO組件非阻塞

2024-04-30 09:02:48

2023-04-26 10:21:04

2024-12-04 08:40:19

2014-05-30 10:23:15

樂跑手環(huán)智能手環(huán)運動手環(huán)

2021-10-28 16:19:37

物聯(lián)網(wǎng)人工智能IoT

2024-06-03 14:27:08

ThisAPIThat

2024-10-15 11:37:06

2024-06-20 08:06:30

2020-10-08 18:58:46

條件變量開發(fā)線程

2022-11-04 14:16:05

點贊
收藏

51CTO技術(shù)棧公眾號