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

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

高洛峰
高洛峰オリジナル
2016-11-21 10:54:221470ブラウズ

1. リフレクション

リフレクション: JAVA リフレクション メカニズムは、どのクラスでも、このクラスのすべてのプロパティとメソッドを知ることができます。どのオブジェクトでも、そのメソッドとプロパティを呼び出すことができます。動的に情報を取得し、オブジェクトのメソッドを動的に呼び出す機能をJava言語のリフレクション機構と呼びます。

クラスを分析したい場合は、まずクラスのバイトコード ファイル オブジェクトを取得する必要があります。この説明では Class クラスのメソッドを使用するため、最初に各バイトコード ファイルに対応する Class 型のオブジェクトを取得する必要があります。リフレクションの操作は、実際には Class オブジェクトを通じて取得されます:

*a, java.lang.reflect.Field: クラスまたはインターフェースの単一フィールドに関する情報と、それに対する動的アクセス権を提供します。反映されたフィールドは、クラス (静的) フィールドまたはインスタンス フィールドの場合があります。オペレーティングクラスのメンバー変数。
*b, java.lang.reflect.Constructor8742468051c85b06f0a0af9e3e506b5c: 操作クラスのコンストラクター。
*c, java.lang.reflect.Method: クラスを操作するメソッド。

リフレクションの基礎を学ぶ前に、インスタンスとして Person オブジェクトを作成します

package com.jalja.org.base.relfect;

public class Person {
    private String name;
    int age;
    public String address;

    public Person() {
    }

    private Person(String name) {
        this.name = name;
    }

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public void show() {
        System.out.println("show");
    }

    public void method(String s) {
        System.out.println("method " + s);
    }

    public String getString(String s, int i) {
        return s + "---" + i;
    }

    private void function() {
        System.out.println("function");
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", address=" + address
                + "]";
    }

}

2. クラス

public static void getClassObject() throws ClassNotFoundException{
        //方式一:Object的getClass()方法
        Person person1=new Person();
        Person person2=new Person();
        Class c1=person1.getClass();
        Class c2=person2.getClass();
        System.out.println(person1==person2);//false
        System.out.println(c1==c2);//true 不管JVM内存中有多少个对象,对于字节码文件来说只有一份
        //方式二:数据类型的静态class属性
        Class c3=Person.class;
        System.out.println(c1==c3);//true
        //方式三:Class 类的静态方法 
        //public static Class<?> forName(String className)throws ClassNotFoundException
        Class c4=Class.forName("com.jalja.org.base.relfect.Person");
        System.out.println(c1==c4);//true
    }

3. java.lang.reflect.Constructor8742468051c85b06f0a0af9e3e506b5c: オブジェクトの Class オブジェクトを取得し、Constructor クラスを使用します。

1. Constructor オブジェクトを取得します

//获取Class 对象所表示的类的构造方法
    public static void getConstructorTest() throws  Exception{
        Class c4=Class.forName("com.jalja.org.base.relfect.Person");
        //1、获取Class 对象所表示的类所有公共构造方法
        //public Constructor<?>[] getConstructors() throws SecurityException
        Constructor [] cs=c4.getConstructors();
        //2、获取Class 对象所表示的类所有构造方法
        //public Constructor<?>[] getDeclaredConstructors() throws SecurityException
        Constructor[] cs2 =c4.getDeclaredConstructors();
        //3、获取Class对象所表示类的指定指定公共构造方法,  parameterTypes 参数是 Class 对象的一个数组 ,是指定数据类型的字节码
        //public Constructor<T> getConstructor(Class<?>... parameterTypes);
        Constructor cs3=c4.getConstructor();//获取公共的无参构造方法的Constructor对象
        //获取 该 构造函数  public Person(String name, int age, String address)
        Constructor cs4=c4.getConstructor(String.class,int.class,String.class);
        //4、获取Clss对象所表示类指定的构造范法官 parameterTypes 参数是 Class 对象的一个数组,它按声明顺序标识构造方法的形参类型的字节码。
        //public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes);
        //获取该构造 函数 private Person(String name)  的Constructor对象
        Constructor cs5=c4.getDeclaredConstructor(String.class);
        
    }

2. Constructor オブジェクトを通じて Class オブジェクトによって表されるクラスのインスタンスを作成します

4. Field オブジェクトを取得します

public static void createObject() throws Exception{
        Class c4=Class.forName("com.jalja.org.base.relfect.Person");
        //使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例
        //public T newInstance(Object... initargs);
        // Person person=new Person()
        Constructor cs3=c4.getConstructor();//获取公共的无参构造方法的Constructor对象
        Object obj=cs3.newInstance();
        
        //Person person=new Person("jalja", 21, "北京");
        Constructor cs4=c4.getConstructor(String.class,int.class,String.class);
        Object obj1=cs4.newInstance("jalja",21,"北京");
        System.out.println(obj1);//Person [name=jalja, age=21, address=北京]
        
        //实例化一个私有的构造函数 private Person(String name)
        //控制java的访问检查
        //public void setAccessible(boolean flag)
        //将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。
        //值为 false 则指示反射的对象应该实施 Java 语言访问检查。 
        Constructor cs5=c4.getDeclaredConstructor(String.class);
        cs5.setAccessible(true);
        Object obj2=cs5.newInstance("张三丰");
        System.out.println(obj2);//Person [name=张三丰, age=0, address=null]
    }

2. Field オブジェクトを通じて、指定されたクラス属性に値を代入します

//获取Class类的Field对象
    public static void getFieldTest() throws Exception{
        Class cs=Class.forName("com.jalja.org.base.relfect.Person");
        //1、public Field[] getFields() throws SecurityException
        //获取Class 对象所表示的类或接口的所有可访问公共(public修饰的)字段
        Field [] fs=cs.getFields(); 
        //2、public Field[] getDeclaredFields() throws SecurityException
        // 获取Class 对象所表示的类或接口所声明的所有字段。包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段
        Field [] fs1=cs.getDeclaredFields(); 
        //3、public Field getField(String name)throws NoSuchFieldException, SecurityException;
        //获取Class 对象所表示的类或接口的指定公共成员(public修饰)字段。name 参数是一个 String,用于指定所需字段的简称
        Field fs2=cs.getField("address");
        //public Field getDeclaredField(String name)  throws NoSuchFieldException,SecurityException
        //获取 Class 对象所表示的类或接口的指定已声明字段。name 参数是一个 String,它指定所需字段的简称
        Field fs3=cs.getDeclaredField("name");
        System.out.println(fs3);
    }

5. java.lang.reflect.Method

1. Method オブジェクトを取得します

//使用 Field对象
    public static void createVarValue() throws Exception{
        Class cs=Class.forName("com.jalja.org.base.relfect.Person");
        Object obj=cs.getConstructor().newInstance();
        Field addressField=cs.getField("address");
        //public void set(Object obj, Object value);
        //将指定对象变量上此 Field 对象表示的字段设置为指定的新值。如果底层字段的类型为基本类型,则对新值进行自动解包
        //obj - 应该修改其字段的对象  value - 正被修改的 obj 的字段的新值 
        addressField.set(obj, "北京");
        System.out.println(obj); //Person [name=null, age=0, address=北京]
        
        //对非public修饰的变量操作
        Field nameField=cs.getDeclaredField("name");
        //控制java的访问检查
        nameField.setAccessible(true);
        nameField.set(obj, "张三丰");
        System.out.println(obj);//Person [name=张三丰, age=0, address=北京]
    }

2. メソッドを通じて、指定されたクラスのメソッドを呼び出しますオブジェクト

rreee

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