JAVA反射整理

7370 ワード

1.反射の意味は何ですか.
Java反射メカニズムとは、実行状態において、いずれのクラスに対しても、このクラスのすべての属性と方法を知ることができることを指す.いずれのオブジェクトに対しても、そのメソッドとプロパティを呼び出すことができます.このような動的に取得された情報および動的にオブジェクトを呼び出す方法の機能をjava言語の反射メカニズムと呼ぶ.クラスのフルネームパスを1つだけ伝えると、反射によって対応するクラスインスタンスを取得することができます.私たちは一般的にClassクラスを使って、この反射されたObjcetクラスの下で、構造方法、属性、または方法などを呼び出し、いくつかのオープンソースフレームワークで非常に多くの反射を使用します.Spring、Struts、Hibnerate、MyBaticsには影があります.
一言で言えばjavaが動的に取得したクラスのメソッド属性とオブジェクトを動的に呼び出すメソッドの機能を反射と呼ぶ.
2つの異なる状態:
静的コンパイル:コンパイル時にタイプを決定し、オブジェクトをバインドします.
動的コンパイル:実行時にタイプを決定し、オブジェクトをバインドします.動的コンパイルはjavaの柔軟性を最大限に発揮し、多態の応用を体現し、クラス間のレンコンの整合性を低下させる.
2.反射メカニズムの利点と欠点?
メリット:
(1)実行時にクラスのインスタンスを動的に取得でき,システムの柔軟性と拡張性を大幅に向上させる.
(2)Javaダイナミックコンパイルと組み合わせることで、非常に強力な機能を実現
欠点:
(1)反射を使用する性能が低い
(2)反射の使用は相対的に安全ではない
(3)クラスのカプセル化性を破壊し,このクラスのプライベートメソッドと属性を反射により取得できる.
2.反射の使い方と例は?
Java反射に必要なクラスは多くありません.主にjava.lang.Classクラスとjava.lang.reflectパッケージのField、Constructor、Method、Arrayクラスがあります.
注意:ClassクラスはJava反射の起源であり、探査したいクラスのいずれかに対して、Classクラスのオブジェクトを先に生成してから、Classオブジェクトを通じて他の情報を取得することができます.
JAva反射では、Classオブジェクト、クラス名、修飾子、パッケージ情報、親、実装インタフェース、コンストラクタ、メソッド、変数、注釈などの情報を取得できます.
さあ、オブジェクトを作成して、それぞれの方法を試してみましょう.詳しくは説明しません.Person Class
public class Person implements Action {
    private String name;
    private int age;
    private String head;
    protected List stringList = new ArrayList<>();
    private String privateString = null;

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

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("    :" + name);
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getHead() {
        return head;
    }

    public void setHead(String head) {
        this.head = head;
    }

    @Override
    public String toString() {
        return "Person{" +
                       "name='" + name + '\'' +
                       ", age=" + age +
                       ", head='" + head + '\'' +
                       '}';
    }


    public Person(String name, String privateString) {
        this.name = name;
        this.privateString = privateString;
    }


    public void setPrivateString(String privateString) {
        this.privateString = privateString;
    }

    private String getPrivateString() {
        return this.privateString;
    }


    public List getStringList() {
        return this.stringList;
    }

    public void setStringList(List stringList) {
        this.stringList = stringList;
    }

    @Override
    public void run() {

    }

    @Override
    public void jump() {

    }

    @Override
    public void rotate() {

    }

}

ActionインタフェースクラスPersonサブクラスは純粋にテストの1つの方法です
public class Hero extends Person {
public Hero(String name, int age, String head) {
    super(name, age, head);
}
}

//Classオブジェクト'Class className=Class.forName("com.java.study.reflect.Person");'//クラス名を取得し、パッケージ名'System.out.println("Name:"+className.getName();'//クラス名のみ取得パッケージ名'System.out.println("SimpleName:"+className.getSimpleName();'//クラスのModifiers修飾子int modifiers=className.getModifiers()を取得します.System.out.println(「クラスが抽象的かどうか:」+Modifier.isAbstract(modifiers));System.out.println(「Finalで修飾するかどうか:」+Modifier.isFinal(modifiers));System.out.println("isInterface:"+ Modifier.isInterface(modifiers)); System.out.println("isNative:"+ Modifier.isNative(modifiers)); System.out.println("isPrivate:"+ Modifier.isPrivate(modifiers)); System.out.println("isProtected:"+ Modifier.isProtected(modifiers)); System.out.println("isPublic:"+ Modifier.isPublic(modifiers)); System.out.println("isStatic:"+ Modifier.isStatic(modifiers)); System.out.println("isStrict:"+ Modifier.isStrict(modifiers)); System.out.println("isSynchronized:"+ Modifier.isSynchronized(modifiers)); System.out.println("isTransient:"+ Modifier.isTransient(modifiers)); System.out.println("isVolatile:"+ Modifier.isVolatile(modifiers));//Hero Class ' Class hero = Class.forName("com.java.study.reflect.Hero");'
//パッケージの情報'System.out.println("パッケージ名:"+hero.getName();'//親の情報を取得(親の情報を取得できます)'System.out.println(「クラスオブジェクトはクラスの親にアクセスできます:」+hero.getSuperclass().getName();'//クラスのインタフェースClass[]interfaces=className.getInterfaces();if(interfaces.length>0){System.out.println(「統合インタフェースの名前:」+interfaces[0].getName()
//Classオブジェクトに基づいてConstructorクラスConstructor[]constructors=className.getConstructors();if(constructors.length>0){Class[]parameterType=constructors[0].getParameterType();System.out.println(「構築パラメータ配列:」+parameterType[0]);}//反射でフィールドを返す値Field[]fields=className.getFields();Person person=new Person(「明」);Field privateStringField = Person.class.getDeclaredField("name");//setAccessible()メソッドは、指定されたクラスFieldインスタンスの反射アクセスチェックを閉じます.この行のコードが実行されると、プライベート、保護され、パケットアクセスの役割ドメインにかかわらず、//アクセス権限の役割ドメイン内にいなくても、どこでもアクセスできます.しかし、通常のコードで権限の役割ドメイン内にないコードにアクセスすることはできません.//コンパイル時にエラーが表示されます.privateStringField.setAccessible(true); String fieldValue = (String) privateStringField.get(person); System.out.println("fieldValue = "+ fieldValue);
        //             
        Person person2 = new Person("  ", "The Private Value");
        Method privateStringMethod = Person.class.getDeclaredMethod("getPrivateString", null);
        privateStringMethod.setAccessible(true);
        String returnValue = (String) privateStringMethod.invoke(person2, null);
        System.out.println("returnValue = " + returnValue);

        //      
        Method method = Person.class.getMethod("getStringList", null);
        Type returnType = method.getGenericReturnType();
        if (returnType instanceof ParameterizedType) {
            ParameterizedType type = (ParameterizedType) returnType;
            Type[] typeArgument = type.getActualTypeArguments();
            for (Type typeItem : typeArgument) {
                Class typeArgClass = (Class) typeItem;
                System.out.println("typeArgClass = " + typeArgClass);
            }
        }

        Method method2 = Person.class.getMethod("setStringList", List.class);
        Type[] genericParameterTypes = method2.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
            if (genericParameterType instanceof ParameterizedType) {
                ParameterizedType aType = (ParameterizedType) genericParameterType;
                Type[] parameterArgTypes = aType.getActualTypeArguments();
                for (Type parameterArgType : parameterArgTypes) {
                    Class parameterArgClass = (Class) parameterArgType;
                    System.out.println("parameterArgClass = " + parameterArgClass);
                }
            }
        }

'''