ホームページ  >  記事  >  Java  >  Javaのリフレクションの基本

Javaのリフレクションの基本

黄舟
黄舟オリジナル
2017-02-24 09:51:161048ブラウズ


1. リフレクションとは


どのクラスでも、このクラスのすべてのメソッドと属性を知ることができ、Any と呼ぶことができます。 のメソッドと属性が /font> の情報を動的に取得し、オブジェクトのメソッドを動的に呼び出すことを Java のリフレクション機構と呼びます。 2. リフレクションの役割

    1. 逆コンパイル: .class–>java
  • 2. リフレクションメカニズムを通じてオブジェクトのプロパティ、メソッド、構築メソッドなどにアクセスします
  • 3. リフレクティブ固有の実装

3.1 リフレクション関連クラス

    java.lang.Class;
  • java.lang.reflect.Constructor;
  • java.lang.reflect.Field;
  • java .lang.reflect.Method;
  • java.lang.reflect.Modifier;
  • 3.2 大きな Class オブジェクトを取得する 3 つの方法

どのクラスも Object のサブクラスであり、Object には getClass があるため、

オブジェクトClassを取得しました -
-public final native Class6b3d0130bba23ae47fe2b8e8cddf0195 getClass();

package com.chb.reflectTest;public class Test {
    public static void main(String[] args) throws Exception {        //第一种方式:
        Class<?> c1 = Class.forName("com.chb.reflectTest.Test");    //第二种方式:java中每个类都有class属性
        Class<?> c2 = Test.class;        //第三种方式:每个对象都与getClass()方法
        Class<?> c3 = new Test().getClass();
    }
}

3.3 オブジェクトを作成します

Class

オブジェクトを取得したら、それを使用してオブジェクトを作成します。 newInstance() を通じてパラメータなしのコンストラクターを呼び出し、オブジェクトを作成します。

Class<?> c1 = Class.forName("com.chb.reflectTest.Test");Object o1 = c1.newInstance();
3.4 . データを取得

全属性と指定属性に分割

3.4.1. すべての属性を取得

    変更を取得
    • まず属性のgetModifiers()で変更オブジェクトを取得します
    • 次に、java.long.reflect.Modifier の toString() を介して、クラスと属性の変更 (public、static、final など) が出力されます。
    属性の取得
    • すべての属性の取得: Class オブジェクトの getDeclaedFields() を通じてフィールド化された配列** を返します。
    属性のタイプを取得します:
    • 属性オブジェクト(Fieldオブジェクト)のgetType()を通して
    • Class<?> cString = Class.forName("java.lang.String");
              //获取累的修饰和名称
              System.out.print(Modifier.toString(cString.getModifiers())+" class " + cString.getSimpleName()+"{\n");
              //获取所有属性
              Field[] fields = cString.getDeclaredFields();
              for (Field field : fields) {
                  System.out.print("\t");
                  System.out.print(
                          Modifier.toString(field.getModifiers())+" "//属性的修饰
                        + field.getType().getSimpleName()+" "
                        + field.getName()+"\n");           
              }
              System.out.println("}");
    3.4.2 指定された属性を取得します

テストオブジェクトを作成します:

注: 私は次のテスト リフレクションでカプセル化を解除できるように、Use クラスで 2 つのプロパティが定義されています。

package com.chb.reflectTest;public class User {    
private String name;    
public  String nickName;    
public User() {}    
public User(String name, String nickName) {        
this.name = name;        
this.nickName = nickName;
    }
    setter getter...

}
従来の属性の取得とリフレクションによる取得の比較:

package com.chb.reflectTest;import java.lang.reflect.Field;public class Test1 {
    public static void main(String[] args) throws Exception {
        //传统获取属性的值
        //1、通过getter,setter
        User user1 = new User();
        user1.setName("lisi");
        System.out.println(user1.getName());
        //2、直接调用属性
        User user2 = new User();
        user2.nickName = "癞皮狗";
        System.out.println(user2.nickName);
        //=========================================
        //通过反射来设置,获取属性。
        Class<User> c1 = (Class<User>) Class.forName("com.chb.reflectTest.User");
        User user = c1.newInstance();
        Field nickField = c1.getDeclaredField("nickName");
        nickField.set(user, "123");
        System.out.println(nickField.get(user));

        Field nameFiled = c1.getDeclaredField("name");
        //Exception in thread "main" java.lang.IllegalAccessException: 
        Class com.chb.reflectTest.Test1 can not access a member of class com.chb.reflectTest.User with modifiers "private"
        nameFiled.setAccessible(true);
        nameFiled.set(user, "oup");
        System.out.println(nameFiled.get(user));

    }
}

値を設定します。リフレクションによる属性の変更、プライベート属性の変更範囲は直接設定できません

Java の安全なアクセス機構であるアクセスエラーが発生します:

Exception in thread "main" java.lang.IllegalAccessException: Class com.chb.reflectTest.Test1 can not access a member of class com.chb.reflectTest.
User with modifiers "private"

を破るメソッドを使用します。 Java のカプセル化:

nameFiled.setAccessible(true);

1. リフレクションとは

リフレクションの仕組みは、どのクラスでも、どのオブジェクトのメソッドやプロパティもすべて呼び出すことができます。メソッドとプロパティ、これ

ec1fca601d556412b20078a19c015a83 の情報を動的に取得し、オブジェクトのメソッドを動的に呼び出す方法を Java のリフレクション機構と呼びます。

2. リフレクションの役割

1. 逆コンパイル: .class–>java

  • 2. リフレクションメカニズムを通じてオブジェクトのプロパティ、メソッド、構築メソッドなどにアクセスします

  • 3. リフレクティブ固有の実装

  • 3.1 リフレクション関連クラス

java.lang.Class;

  • java.lang.reflect.Constructor;

  • java.lang.reflect.Field;

  • java .lang.reflect.Method;

  • java.lang.reflect.Modifier;

  • 3.2 大きな Class オブジェクトを取得する 3 つの方法

  • どのクラスも Object のサブクラスであり、Object には getClass があるため、

オブジェクト

を取得しました - Class -

package com.chb.reflectTest;public class Test {
    public static void main(String[] args) throws Exception {        //第一种方式:
        Class<?> c1 = Class.forName("com.chb.reflectTest.Test");        //第二种方式:java中每个类都有class属性
        Class<?> c2 = Test.class;        //第三种方式:每个对象都与getClass()方法
        Class<?> c3 = new Test().getClass();
    }
}

3.3 オブジェクトを作成しますpublic final native Class6b3d0130bba23ae47fe2b8e8cddf0195 getClass();

Class

オブジェクトを取得したら、それを使用してオブジェクトを作成します。 newInstance() を通じてパラメータなしのコンストラクターを呼び出し、オブジェクトを作成します。

Class<?> c1 = Class.forName("com.chb.reflectTest.Test");Object o1 = c1.newInstance();

3.4 . データを取得 全属性と指定属性に分割

3.4.1. すべての属性を取得

変更を取得

  • まず属性のgetModifiers()で変更されたオブジェクトを取得します
    • 次に、java.long.reflect.Modifier の toString() を介して、クラスと属性の変更 (public、static、final など) が出力されます。

    • 属性の取得
  • すべての属性の取得: Class オブジェクトの getDeclaedFields() を通じてフィールド化された配列** を返します。
    • 属性のタイプを取得します:
      • 通过属性对象(Field对象)的getType()

    Class<?> cString = Class.forName("java.lang.String");
            //获取累的修饰和名称
            System.out.print(Modifier.toString(cString.getModifiers())+" class " + cString.getSimpleName()+"{\n");
            //获取所有属性
            Field[] fields = cString.getDeclaredFields();
            for (Field field : fields) {
                System.out.print("\t");
                System.out.print(
                        Modifier.toString(field.getModifiers())+" "//属性的修饰
                      + field.getType().getSimpleName()+" "
                      + field.getName()+"\n");           
            }
            System.out.println("}");

    3.4.2 获取指定属性

    创建测试对象:
    注意: 我在Use类中定义了两个属性, 一个public ,一个private ,是为了下一个测试反射可以打破封装性

    package com.chb.reflectTest;public class User {    
    private String name;    
    public  String nickName;    
    public User() {}    
    public User(String name, String nickName) {        
    this.name = name;        
    this.nickName = nickName;
        }
        setter getter...
    
    }

    传统属性的获取和通过反射获取对比:

    package com.chb.reflectTest;import java.lang.reflect.Field;public class Test1 {
        public static void main(String[] args) throws Exception {
            //传统获取属性的值
            //1、通过getter,setter
            User user1 = new User();
            user1.setName("lisi");
            System.out.println(user1.getName());
            //2、直接调用属性
            User user2 = new User();
            user2.nickName = "癞皮狗";
            System.out.println(user2.nickName);
            //=========================================
            //通过反射来设置,获取属性。
            Class<User> c1 = (Class<User>) Class.forName("com.chb.reflectTest.User");
            User user = c1.newInstance();
            Field nickField = c1.getDeclaredField("nickName");
            nickField.set(user, "123");
            System.out.println(nickField.get(user));
    
            Field nameFiled = c1.getDeclaredField("name");
            //Exception in thread "main" java.lang.IllegalAccessException: 
            Class com.chb.reflectTest.Test1 can not access a member of class com.chb.reflectTest.User with modifiers "private"
            nameFiled.setAccessible(true);
            nameFiled.set(user, "oup");
            System.out.println(nameFiled.get(user));
    
        }
    }

    通过反射来设置属性的值, 区别属性的修饰范围, 私有的不可以直接设置
    会出现访问错误, 也就是java的安全访问机制,报错:

    Exception in thread "main" java.lang.IllegalAccessException: Class com.chb.reflectTest.Test1 can not access a member of class com.chb.reflectTest.
    User with modifiers "private"

    我们通过一个方法·来打破java的封装性:

    nameFiled.setAccessible(true);

     以上就是java之反射基础的内容,更多相关内容请关注PHP中文网(www.php.cn)!


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。