ホームページ  >  記事  >  Java  >  Java リフレクション メカニズム

Java リフレクション メカニズム

伊谢尔伦
伊谢尔伦オリジナル
2017-01-16 11:58:121511ブラウズ

プログラムの実行中にプログラムの構造や変数の型を変更できる言語を動的言語と呼びます。 Java は動的言語ではないと考えていますが、一般にリフレクションとして知られる、非常に顕著な動的関連メカニズムを備えています。

IT業界では「反省なくしてフレームワークなし」と言われていますが、既存のフレームワークはすべて反省に基づいています。実際のプロジェクト開発ではフレームワークが最も多く使われ、最も多く埋められるのがクラスです。フレームワークとクラスを結びつける仲介者としてリフレクションという概念があります。したがって、振り返りはプロジェクト開発への布石となります。

リフレクション メカニズムとは何ですか?

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


リフレクション機構でできること

リフレクション機構は主に以下の機能を提供します:

  • 実行時にオブジェクトが属するクラスを判断する

  • 実行時に任意のクラスを構築する。オブジェクト;

  • 実行時に任意のクラスのメンバー変数とメソッドを判断します。

  • 実行時に任意のオブジェクトのメソッドを呼び出します。

  • 具体的な関数実装

1. リフレクション機構を通じてクラスを取得するには3つの方法があります

//第一种方式:  
Classc1 = Class.forName("Employee");  
//第二种方式:  
//java中每个类型都有class 属性.  
Classc2 = Employee.class;  
   
//第三种方式:  
//java语言中任何一个java对象都有getClass 方法  
Employeee = new Employee();  
Classc3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee)
2. オブジェクトを作成します: クラスを取得した後、そのオブジェクトを作成します。 newInstance を使用します:

Class c =Class.forName("Employee");  
  
//创建此Class 对象所表示的类的一个新实例  
Objecto = c.newInstance(); //调用了Employee的无参数构造方法.

3. 属性を取得します: すべての属性と指定された属性に分割します:

まずはすべての属性を取得する方法を見てみましょう:

//获取整个类  
            Class c = Class.forName("java.lang.Integer");  
              //获取所有的属性?  
            Field[] fs = c.getDeclaredFields();  
       
                   //定义可变长的字符串,用来存储属性  
            StringBuffer sb = new StringBuffer();  
            //通过追加的方法,将每个属性拼接到此字符串中  
            //最外边的public定义  
            sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{\n");  
            //里边的每一个属性  
            for(Field field:fs){  
                sb.append("\t");//空格  
                sb.append(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等  
                sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字  
                sb.append(field.getName()+";\n");//属性的名字+回车  
            }  
      
            sb.append("}");  
      
            System.out.println(sb);

特定の属性を取得し、従来の方法と比較して学習します:

public static void main(String[] args) throws Exception{  
              
<span style="white-space:pre">  </span>//以前的方式:  
    /* 
    User u = new User(); 
    u.age = 12; //set 
    System.out.println(u.age); //get 
    */  
              
    //获取类  
    Class c = Class.forName("User");  
    //获取id属性  
    Field idF = c.getDeclaredField("id");  
    //实例化这个类赋给o  
    Object o = c.newInstance();  
    //打破封装  
    idF.setAccessible(true); //使用反射机制可以打破封装性,导致了java对象的属性不安全。  
    //给o对象的id属性赋值"110"  
    idF.set(o, "110"); //set  
    //get  
    System.out.println(idF.get(o));  
}

メソッドの反映

Class クラスには、最も単純なメソッド getName() があります。

public class Demo2 {
public static void main(String[] args) {
Class c1 = int.class;//int 的类类型
Class c2 = String.class;//String类的类类型
Class c3 = void.class;
System.out.println(c1.getName());
System.out.println(c2.getName());
System.out.println(c2.getSimpleName());
System.out.println(c3.getName());
}
}

getName メソッドは、このクラス型のクラス名を出力できます。 getSimpleName() メソッドを使用して出力することもできます。パッケージ名を含まないクラス名。上記のコードからわかるように、基本的なデータ型と void キーワードはすべてクラス型に存在します。

ケース:

public class ClassUtil {
public static void printClassMethodMessage(Object obj){
//要获取类的信息》》首先我们要获取类的类类型
Class c = obj.getClass();
//我们知道Object类是一切类的父类,所以我们传递的是哪个子类的对象,c就是该子类的类类型。
//接下来我们要获取类的名称System.out.println("类的名称是:"+c.getName());
/*
*我们知道,万事万物都是对象,方法也是对象,是谁的对象呢?
* 在java里面,方法是Method类的对象
*一个成员方法就是一个Method的对象,那么Method就封装了对这个成员
*方法的操作
*///如果我们要获得所有的方法,可以用getMethods()方法,这个方法获取的是所有的Public的函数,包括父类继承而来的。如果我们要获取所有该类自己声明的方法,就可以用getDeclaredMethods()方法,这个方法是不问访问权限的。
Method[] ms = c.getMethods();//c.getDeclaredMethods()
//接下来我们拿到这些方法之后干什么?我们就可以获取这些方法的信息,比如方法的名字。
//首先我们要循环遍历这些方法
for(int i = 0; i < ms.length;i++){
//然后可以得到方法的返回值类型的类类型
Class returnType = ms[i].getReturnType();
//得到方法的返回值类型的名字
System.out.print(returnType.getName()+" ");
//得到方法的名称
System.out.print(ms[i].getName()+"(");
//获取参数类型--->得到的是参数列表的类型的类类型
Class[] paramTypes = ms[i].getParameterTypes();
for (Class class1 : paramTypes) {
System.out.print(class1.getName()+",");
}
System.out.println(")");
}
}
}

概要のアイデア: メソッド リフレクションを通じてクラスの名前を取得する 手順:

1. クラスのクラス タイプを取得する

2. クラス タイプを介してクラス メソッド (getMethods()) を取得する

3取得したメソッドをループします

4. これらのメソッドの getReturnType() で戻り値の型のクラス型を取得し、getName でメソッドの名前を取得します。 () を実行し、getParameterTypes() でメソッドの名前を取得します。 このメソッドのパラメータ型のクラス型。



メンバー変数のリフレクション


まず第一に、メンバー変数もオブジェクト、つまり java.lang.reflect.Field クラスのオブジェクトであることを認識する必要があります。つまり、Field クラスは操作をカプセル化します。メンバー変数。メンバー変数をカプセル化するので、これらのメンバー変数を取得するにはどうすればよいでしょうか?このようなメソッドがあります:

public class ClassUtil {
public static void printFieldMessage(Object obj){
Class c = obj.getClass();
//Field[] fs = c.getFields();
}
ここでの getFields() メソッドは、すべてのパブリック メンバー変数の情報を取得します。そして、リフレクション メソッドのパブリック メンバー変数には、自分で宣言したすべてのメンバー変数の情報を取得する方法もあります:
Field[] fs = c.getDeclaredFields();

取得後、トラバースできます (フィールド情報がカプセル化されているため、取得できます)フィールドの型)

for (Field field : fs) {
//得到成员变量的类型的类类型
Class fieldType = field.getType();
String typeName = fieldType.getName();
//得到成员变量的名称
String fieldName = field.getName();
System.out.println(typeName+" "+fieldName);
}

コンストラクターのリフレクション

メソッドのリフレクション、メンバー変数のリフレクション、コンストラクターのリフレクションのいずれであっても、知っておく必要があるのは、クラス情報を取得するには、まずクラスのクラス型を取得する必要があるということだけです。 。

りー

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