ホームページ  >  記事  >  Java  >  Java のアセンブリのロードとリフレクションのメカニズムとは何ですか?

Java のアセンブリのロードとリフレクションのメカニズムとは何ですか?

王林
王林転載
2023-05-07 13:25:07722ブラウズ

1. アセンブリの読み込み

JIT コンパイラーは IL コードをローカル コードにコンパイルするときに、IL コード内でどの型が参照されているかを確認します。実行時、JIT コンパイラはアセンブリの TypeRef および AssemblyRef メタデータ テーブルを使用して、参照される型を定義するアセンブリを決定します。その後、JIT コンパイラは対応するアセンブリを AppDomain に読み込みます。内部的に、CLR は .Reflection の System The static メソッド Load を使用します。アセンブリ クラスはアセンブリの読み込みを試みます。ただし、アセンブリを動的にロードする場合は、Assembly の Load メソッドを使用してアセンブリを動的にロードできます。Assembly クラスには、LoadFrom(string path)、LoadFile(stringassemblyFile) などの他のロード アセンブリ メソッドも提供されます。

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

.net のリフレクションは、実行中にアセンブリ内のメタデータを解析し、型のメンバー (フィールドやコンストラクターを含む)、メソッド、プロパティ、イベントなど)情報。

アセンブリを動的に読み込み、型のメンバーを取得します。

次のクラスをクラス ライブラリ プロジェクトに配置し、アセンブリをコンパイルして生成します (たとえば、DLL が ClassLibrary1.dll であると仮定します)。これをドライブ D のルート ディレクトリに配置します)

public class ReflectTestClass    {       public  string name;       public int age;       public string Name       {           get { return name; }           set { name = value; }       }        public int Age       {           get { return age; }           set { age = value; }       }         /// <summary>        /// No Paramter Constructor        /// </summary>       public ReflectTestClass()       {        }         /// <summary>        /// Constructor with Parameter        /// </summary>        /// <param name="name"></param>        /// <param name="age"></param>        public ReflectTestClass(string names,int ages)        {            this.name = names;            this.age = ages;        }         public string writeString(string name)        {            return "Welcome " + name;        }         public static string WriteName(string name)        {            return "Welcome "+name +" Come here";        }         public string WirteNopara()        {            return "The method is no parameter ";        }    }

次に、上記で生成されたアセンブリと出力型のメンバーを動的に読み込むコンソール プログラムを作成します。詳細な紹介はコードにあります。

class Program     {         static void Main(string[] args)         {             Assembly ass;             Type[] types;             Type typeA;             object obj;             try             {                 // 从本地中 加载程序集 然后从程序集中通过反射获得类型的信息的,并且调用方法                 ass = Assembly.LoadFrom(@"D:\ClassLibrary1.dll");                 types = ass.GetTypes();                 foreach (Type type in types)                 {                     Console.WriteLine("Class Name is " + type.FullName);                     Console.WriteLine("Constructor Information");                     Console.WriteLine("-----------------------");                     // 获取类型的结构信息                     ConstructorInfo[] myconstructors = type.GetConstructors();                     ShowMessage<ConstructorInfo>(myconstructors);                      Console.WriteLine("Fields Information");                     Console.WriteLine("-----------------------");                     // 获取类型的字段信息                     FieldInfo[] myfields = type.GetFields();                     ShowMessage<FieldInfo>(myfields);                      Console.WriteLine("All Methods Information");                     Console.WriteLine("-----------------------");                     // 获取方法信息                     MethodInfo[] myMethodInfo = type.GetMethods();                     ShowMessage<MethodInfo>(myMethodInfo);                      Console.WriteLine("All Properties Information");                     Console.WriteLine("-----------------------");                     // 获取属性信息                     PropertyInfo[] myproperties = type.GetProperties();                     ShowMessage<PropertyInfo>(myproperties);                 }                  // 用命名空间+类名获取类型                 typeA = ass.GetType("ClassLibrary1.ReflectTestClass");                                  // 获得方法名称                  MethodInfo method = typeA.GetMethod("writeString");                  // 创建实例                 obj = ass.CreateInstance("ClassLibrary1.ReflectTestClass");                  string result = (String)method.Invoke(obj,new string[] {"Tom"});                 Console.WriteLine("Invoke Method With Parameter");                 Console.WriteLine("-----------------------");                 Console.WriteLine(result);                 Console.WriteLine("-----------------------");                 Console.WriteLine();                 method = typeA.GetMethod("WriteName");                 result = (string)method.Invoke(null,new string[] {"Tom"});                 Console.WriteLine("Invoke Static Method with Parameter");                 Console.WriteLine("-----------------------");                 Console.WriteLine(result);                 Console.WriteLine("-----------------------");                 Console.WriteLine();                 method = typeA.GetMethod("WirteNopara");                 Console.WriteLine("Invoke Method with NOParameter");                 result = (string)method.Invoke(obj, null);                 Console.WriteLine("-----------------------");                 Console.WriteLine(result);                 Console.WriteLine("-----------------------");             }              catch(FileNotFoundException ex)             {                 Console.WriteLine(ex.Message);             }              Console.ReadLine();         }          /// <summary>         /// 显示数组信息         /// </summary>         /// <typeparam name="T"></typeparam>         /// <param name="os"></param>         public static void ShowMessage<T>(T[] array)         {              foreach(T member in array)             {                 Console.WriteLine(member.ToString());             }              Console.WriteLine("-----------------------");             Console.WriteLine();         }     }

返されたメンバーの型をフィルターする

Type の GetMembers、GetFields、GetMethods、GetProperties、または GetEvenents メソッドを呼び出して、型のメンバーをクエリできます。上記のメソッドのいずれかを呼び出すときは、System.Reflection.BindingFlags 列挙型のインスタンスを渡すことができます。この列挙型を使用する目的は、これらのメソッドによって返されるメンバーをフィルター処理することです。

注: メンバー コレクションを返すすべてのメソッドの中には、実際のパラメーターを取得しないオーバーロードされたバージョンがあります。 BindingFlags 実パラメータが渡されない場合、これらのメソッドはすべてパブリック メンバーを返し、デフォルト設定は BindingFlags.Public|BindingFlags.Instance|BindingFlags.Static です (Public または NonPublic が指定されている場合は、Instance も同時に指定する必要があります)。そうでない場合、メンバーは返されません)。

以上がJava のアセンブリのロードとリフレクションのメカニズムとは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。