成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java 的反射、內省,你會用嗎?

開發 前端
反射是Java語言的一個特性,允許程序在運行時檢查和操作類、方法、字段等。反射可以動態地獲取類的所有屬性和方法,并且可以動態調用這些方法。

你好,我是看山。

Java的反射和內省是兩個在運行時操作類和對象的強大機制,它們之間存在關聯和區別。很多時候我們用錯了,就會有性能上的損失。

概念

反射(Reflection)

反射是Java語言的一個特性,允許程序在運行時檢查和操作類、方法、字段等。反射可以動態地獲取類的所有屬性和方法,并且可以動態調用這些方法。

反射強調的是運行狀態,即在程序運行時能夠訪問和修改類的狀態或行為。反射提供了更底層的類結構和行為訪問機制。

反射的核心類都在java.reflect包下,主要類如下:

圖片圖片

圖片圖片

內省(Introspection)

內省是基于反射實現的,主要用于操作符合JavaBean規范的類。

JavaBean是一種特殊的Java類,通常用于封裝多個屬性為一個單一的對象。

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

內省操作只針對JavaBean,只有符合JavaBean規則的類的成員才可以采用內省API進行操作。

內省的核心類在java.beans包下,主要類如下:

圖片圖片

關系與區別

  • 適用范圍:

反射可以操作任何類的所有成員,包括私有成員。

內省主要針對JavaBean,只能操作符合JavaBean規范的類的成員。

  • 操作方式:
  • 反射是先得到類的字節碼(Class)后再進行各種操作。
  • 內省是先得到屬性描述器(PropertyDescriptor)后再進行各種操作。
  • 復雜度:
  • 反射提供了更底層的訪問機制,使用起來相對復雜。
  • 內省提供了一套比較簡單和有層次的API,更專注于JavaBean的屬性操作。
  • 應用場景:
  • 反射適用于需要動態獲取和調用類信息的場景,如框架開發。
  • 內省適用于需要操作JavaBean屬性的場景。

來點小栗子

使用反射創建對象并調用方法

我們通過反射創建對象并調用指定方法:

public static void main(String[] args)
        throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException,
        IllegalAccessException, NoSuchFieldException {
    final Class<?> clazz = MyClass.class;
    // Class<?> clazz = new MyClass().getClass();
    // Class<?> clazz = Class.forName("cn.howardliu.tutorials.core.reflect.ReflectDemo.MyClass");

    final Constructor<?> constructor = clazz.getConstructor();
    // Constructor<?> constructor = clazz.getConstructor(String.class);
    final Object o = constructor.newInstance();

    final Field field = clazz.getDeclaredField("name");
    field.setAccessible(true);
    field.set(o, "看山");

    final Method method = clazz.getMethod("echoName");
    final Object result = method.invoke(o);
    System.out.println(result);
}

@Data
@NoArgsConstructor
@AllArgsConstructor
publicstaticclass MyClass {
    private String name;

    public String echoName() {
        return name;
    }
}

首先,我們獲取class對象,有三種方式:

  • 通過類名直接獲取:Class<?> clazz = MyClass.class;
  • 通過實例獲取:Class<?> clazz = new MyClass().getClass();
  • 通過加載類:Class<?> clazz = Class.forName("cn.howardliu.tutorials.core.reflect.ReflectDemo.MyClass"); 。

然后獲取構造器對象,使用Class對象的getConstructor()或getDeclaredConstructor()方法獲取構造器對象。

  • 無參構造函數:Constructor<?> constructor = clazz.getConstructor();
  • 有參構造函數:Constructor<?> constructor = clazz.getConstructor(String.class); 。

使用newInstance()創建實體對象:final Object o = constructor.newInstance();。

示例中我們對name屬性賦值,首先得獲取Field對象,可以用getDeclaredField()或者getField()。

因為name屬性是非public的,調用setAccessible設置可訪問,然后賦值。

最后就是獲取Method對象,使用invoke方法實現對象的動作。

以上就是反射常用的邏輯了。反射還提供了基于枚舉的API,有需要的時候可以用一用。

通過內省給對象賦值

內省就是轉為JavaBean準備的,主要包括下面幾個類:

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

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

使用屬性的讀方法獲取數據,使用寫方法賦值。

public static void main(String[] args)
        throws IntrospectionException, InvocationTargetException, IllegalAccessException {
    final BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
    final User user = new User();

    // 遍歷所有屬性描述符
    for (PropertyDescriptor prop : beanInfo.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);
}

@Data
publicstaticclass User {
    private String username;
}

在JavaBean的操作方面,內省確實比反射更方便。

文末總結

今天通過示例介紹了Java的反射和內省,下次我們看看在Bean賦值方面,兩者的性能差異有多少。

責任編輯:武曉燕 來源: 看山的小屋
相關推薦

2025-01-10 00:00:00

內省機制JavaBean描述器

2010-03-12 08:55:06

Java內省反射

2020-06-04 14:15:55

Java中BigDecimal函數

2018-09-29 15:34:34

JavaList接口

2025-01-15 00:00:00

Java內省性能

2019-07-25 12:46:32

Java高并發編程語言

2023-11-01 13:48:00

反射java

2024-03-06 08:15:03

@Autowired注入方式Spring

2021-05-21 12:36:16

限流代碼Java

2023-12-01 11:13:50

JavaTreeSet

2021-09-06 10:42:18

Linux命令服務器

2021-08-11 10:00:51

緩存MyBatis管理

2019-01-28 17:42:33

Python數據預處理數據標準化

2025-01-03 08:40:53

Java并發編程Guava庫

2021-11-03 17:40:51

Python線程

2024-04-08 00:00:00

asyncawaiPromise

2022-02-10 09:04:50

架構

2009-07-14 18:09:08

Jython的內省

2011-02-28 09:51:43

內省

2015-09-06 10:14:21

swift加載動畫實例教程
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩高清三区 | www.国产一区| 4hu最新网址| 国产精品一区二区无线 | 日韩视频在线一区 | 极情综合网 | 成年人在线视频 | 五月天天丁香婷婷在线中 | 成人在线免费视频观看 | 国产精品免费一区二区 | 天天搞夜夜操 | 亚洲精品久久久久中文字幕欢迎你 | 毛片视频网站 | 久久久久久亚洲精品不卡 | 久草新在线 | 超碰伊人 | 日本久草 | 日本网站免费观看 | 操视频网站 | 99久久免费精品视频 | 国产一区二区成人 | 啪啪毛片| 中文字字幕一区二区三区四区五区 | 在线观看亚洲 | 成人黄色av网址 | 国产在线二区 | 在线播放国产一区二区三区 | 91亚洲国产 | 日韩一区二区三区在线 | 欧洲在线视频 | 久久狠狠 | 成人在线精品视频 | 成年视频在线观看 | 精品视频在线观看 | 亚洲精品一区二区三区蜜桃久 | 日韩一区中文字幕 | 欧美精品一区二区三区在线 | 国产视频二区 | www久久 | 成人在线中文字幕 | 国产成人免费视频网站视频社区 |