Heim >Java >javaLernprogramm >Was sind Mechanismen zum Laden und Reflektieren von Assemblys in Java?

Was sind Mechanismen zum Laden und Reflektieren von Assemblys in Java?

王林
王林nach vorne
2023-05-07 13:25:07737Durchsuche

1. Laden der Assembly

Wenn der JIT-Compiler den IL-Code in lokalen Code kompiliert, prüft er, auf welche Typen im IL-Code verwiesen wird. Während der Laufzeit ermittelt der JIT-Compiler anhand der TypeRef- und AssemblyRef-Metadatentabellen, welche Assembly den referenzierten Typ definiert. Anschließend lädt die CLR die entsprechende Assembly in die AppDomain. Die Assembly-Klasse versucht, eine Assembly zu laden. Wenn wir jedoch eine Assembly dynamisch laden möchten, können wir die Load-Methode von Assembly verwenden, um die Assembly dynamisch zu laden. Die Assembly-Klasse bietet auch andere Lade-Assembly-Methoden, einschließlich LoadFrom(string path), LoadFile(stringassemblyFile) usw.

2. Reflection-Mechanismus

In .net analysiert Reflection die Metadaten in der Assembly während der Ausführung und ruft Informationen über Mitglieder des Typs ab (einschließlich Felder, Konstruktoren, Methoden, Eigenschaften, Ereignisse usw.).

Laden Sie dynamisch eine Assembly und rufen Sie die Mitglieder des Typs ab.

Fügen Sie die folgende Klasse in ein Klassenbibliotheksprojekt ein, kompilieren und generieren Sie die Assembly (z. B. ClassLibrary1.dll, vorausgesetzt, die DLL befindet sich im Stammverzeichnis von

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 ";        }    }

Dann erstellen Sie ein Konsolenprogramm, um die oben generierte Assembly und die Mitglieder des Ausgabetyps dynamisch zu laden. Eine detaillierte Einführung finden Sie im Code.

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();         }     }

Filtern Sie die zurückgegebenen Mitgliedstypen

Sie können die Methoden „GetMembers“, „GetFields“, „GetMethods“, „GetProperties“ oder „GetEvenents“ von Type aufrufen, um die Mitglieder eines Typs abzufragen. Wenn Sie eine der oben genannten Methoden aufrufen, können Sie eine Instanz des Aufzählungstyps System.Reflection.BindingFlags übergeben. Der Zweck der Verwendung dieses Aufzählungstyps besteht darin, die von diesen Methoden zurückgegebenen Mitglieder zu filtern.

Hinweis: Unter allen Methoden, die eine Member-Sammlung zurückgeben, gibt es eine überladene Version, die keine tatsächlichen Parameter erhält. Wenn der eigentliche Parameter BindingFlags nicht übergeben wird, geben alle diese Methoden öffentliche Mitglieder zurück und die Standardeinstellung ist BindingFlags.Public|BindingFlags.Instance|BindingFlags.Static (Wenn Public oder NonPublic angegeben ist, muss gleichzeitig Instance angegeben werden. andernfalls wird kein Mitglied zurückgegeben).

Das obige ist der detaillierte Inhalt vonWas sind Mechanismen zum Laden und Reflektieren von Assemblys in Java?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen