ホームページ  >  記事  >  Java  >  Java イントロスペクション メカニズムを実装する方法

Java イントロスペクション メカニズムを実装する方法

WBOY
WBOY転載
2023-04-24 08:04:061544ブラウズ

    概念

    JavaBean

    実際のプログラミングでは、 Student 、 Employee 、 Order などの値オブジェクトをラップするいくつかのクラスが必要になることがよくあります。多くの場合、これらのクラスにはビジネス メソッドはなく、処理する必要があるエンティティ オブジェクトをカプセル化するだけです。これらには次の特徴があります:

    • プロパティはすべてプライベートです;

    • パラメーターのないパブリック コンストラクターがあります。

    • 必要に応じて、プライベート プロパティのパブリック getXxx メソッドと setXxx メソッドを提供します。

    • 例: 属性名が name の場合、getName メソッドは属性名の値を返し、setName メソッドは名前の値を設定します。メソッドの名前は通常、get または set に属性を加えたものであることに注意してください。名前、属性名の最初の文字は大文字です。これらのメソッドはゲッター/セッターと呼ばれます。ゲッターには戻り値が必要ですが、メソッド パラメーターは必要ありません。セッター値には戻り値がなく、メソッド パラメーターがあります。

    たとえば、次の例:

    Java イントロスペクション メカニズムを実装する方法これらの特性を満たすクラスは JavaBeans と呼ばれます;

    イントロスペクション

    イントロスペクション ( Inspector) メカニズムはリフレクションに基づいています Java 言語には Bean クラスの属性とイベントが欠如しています 保存処理メソッド

    クラス内に getXXX メソッド、setXXX メソッド、または getXXX メソッドと setXXX メソッドの両方が存在する限り、getXXX メソッドにはメソッド パラメータがなく戻り値があり、setXXX メソッドには戻り値がなく、メソッドパラメータがある; イントロスペクション このメカニズムは XXX を属性とみなします;

    たとえば、以下のコードでは

    # 従業員クラスでは年齢属性がまったく宣言されていません。イントロスペクション メカニズムは、年齢を属性とみなします

    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 インターフェース
    • : 直接インスタンス化することはできません。このタイプのオブジェクトは通常、プロパティ記述子オブジェクト (PropertyDescriptor)、メソッド記述子オブジェクト (MethodDescriptor) を返すためのメソッドを提供する Introspector クラスを通じて返されます。 、および Bean 記述子 (BeanDescriptor) オブジェクト;

    • Java.beans.PropertyDescriptor クラス
    • : ゲッター メソッドとセッター メソッドを持つプロパティを記述するために使用されます。

      PropertyDescriptor クラスのメソッドを使用して、プロパティ関連の情報を取得できます。たとえば、getName メソッドはプロパティの名前を返します。

    • PropertyDescriptor クラスは、次のようなメソッドを定義します。プロパティのゲッター メソッドとセッター メソッドを取得します。

    メソッドメソッドの説明属性に対応する getter メソッド オブジェクトを返します;属性に対応する setter メソッド オブジェクトを返します;コードを使用して詳しく調べてみましょう:コード ケース: 属性関連情報の取得
    メソッド getReadMethod()
    Method getWriteMethod()

    従業員 上記のコードに示されているように、テスト用の main 関数の作成を続行します。

    最初に 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());
    }

    実行結果は次のとおりです。

    #ここで取得した 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 イントロスペクション メカニズムを実装する方法

    すべてのコードは下部に添付されています。 ! ! ! ! ! Java イントロスペクション メカニズムを実装する方法

    イントロスペクション プロパティに関する注意事項

    多くのフレームワークは、オブジェクトのプロパティを取得するためにイントロスペクション メカニズムを使用します。プロパティ名を定義するとき、名前は次のようになります。 sName を使用する代わりに、少なくとも 2 つの小文字 (stuName など) で始めることをお勧めします。場合によっては、属性の取得が失敗する可能性があります。メカニズムは属性を取得し、それに基づいています 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=&#39;" + name + &#39;\&#39;&#39; +
                      ", score=" + score +
                      &#39;}&#39;;
          }
      
          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 イントロスペクション メカニズムを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。