Javaバイトコードとリフレクションメカニズム

    バイトコードは、Java言語のクロスプラットフォーム機能の重要な保証であり、リフレクションメカニズムの重要な基盤です。リフレクションメカニズムを通じて、あるクラスの属性とメソッドを確認できるだけでなく、あるクラスの別のクラスのメソッドを呼び出すこともできますが、関連するバイトコードファイル(つまり、.classファイル)がある場合に限ります。クラス。

1バイトコードと.classファイル

    拡張子が.javaのファイルを作成した後、実行できる場合(たとえば、main関数が含まれている場合)、MyEclipseの[実行]ボタンをクリックして.javaファイルを実行できます。

    ただし、現時点では、MyEclipseは重要なステップを隠しています。最初に.javaファイルを拡張子.classのバイトコードファイルにコンパイルし、次にJava仮想マシン(JVM)を現在のオペレーティングシステム上に配置します(たとえば、 、この.classファイルをウィンドウ10)で実行します。

    つまり、.javaファイルを実行する前に.classファイルにコンパイルする必要があります。さらに驚くべきことは、ウィンドウ7システムでコンパイルされた.classファイルをLinuxシステムで直接実行できることです(もちろん、これはこれはJavaのクロスプラットフォーム機能であり、「どこでもコンパイルして実行する」機能とも呼ばれます。

    リフレクションのトピックに戻ります。.classのバイトコードファイルを取得できる限り、リフレクションメカニズムを介して、に対応するJavaファイル内の属性メソッドやその他の情報を確認できるだけではありません。 this .classですが、呼び出しも行います。これは、Javaファイルのメソッドに対応します。

2クラスクラス(Cは大文字)は、リフレクション実装の文法的基礎です。

    一部のツールでは、.classファイルを開いて、それに含まれる属性とメソッドを確認できますが、.classファイルに対して直接プログラムすることはできません。クラスを使用する必要があります(Cは大文字です)。

    Classクラスのフルネームはjava.lang.Classです。クラスまたはインターフェイス(つまり、javaファイルのコンパイル済みクラスファイル)がJava仮想マシン(JVM)にロードされると、それに関連付けられたjavaは次のようになります。生成された.lang.Classオブジェクト、コードのリフレクション部分では、通常、このクラスを介してターゲットクラスのプロパティとメソッドにアクセスして使用します。

    リフレクションメカニズムにより、指定されたクラスの属性(属性修飾子、属性、タイプと属性の変数名など)を.classファイルから確認できます。次のReflectionReadVar.javaを通じて、デモンストレーションの下での特定のアプローチを見ていきます。    

1	import java.lang.reflect.Field;
2	import java.lang.reflect.Modifier;
3	class MyValClass{
4		private int val1;
5		public String val2;
6		final protected String val3 = "Java";
7	}

    3行目でMyValCalssクラスを定義し、4行目から6行目で3つの属性変数を定義しました。    

8	public class ReflectionReadVar {
9		public static void main(String[] args) {
10			Class<MyValClass> clazz = MyValClass.class;
11			//获取这个类的所有属性
12	        Field[] fields = clazz.getDeclaredFields();
13		    for(Field field : fields) {
14		    	   //输出修饰符	    	   System.out.print(Modifier.toString(field.getModifiers()) + "\t");
15		    	   //输出属性的类型
16		       System.out.print(field.getGenericType().toString() + "\t");
17		    	   //输出属性的名字
18		    	   System.out.println(field.getName());
19		      }
20		}
21	}

     メイン関数の10行目で、MyValClass.classを介して、Class <MyValClass>型の変数clazzを取得します。この変数には、クラスMyValClassの一部の情報が格納されます。

    12行目では、clazz.getDeclaredFields()メソッドを使用して、MyValClassクラスのすべての属性の情報を取得し、これらの属性の情報をField配列型のfields変数に格納します。

    13行目を通過したforループは、これらの属性情報を順番に出力します。具体的には、属性の修飾子は14行目のコードで出力され、属性のタイプは16行目のコードで出力され、属性の変数名は18行目のコードで出力されます。このコードの出力は次のとおりであり、そこから各属性の情報を確認できます。

  1. private int val1
  2. パブリッククラスjava.lang.Stringval2
  3. 保護された最終クラスjava.lang.Stringval3

おすすめ

転載: blog.csdn.net/sxeric/article/details/113058457