Maison  >  Article  >  Java  >  Que sont les mécanismes de chargement et de réflexion d’assembly en Java ?

Que sont les mécanismes de chargement et de réflexion d’assembly en Java ?

王林
王林avant
2023-05-07 13:25:07722parcourir

1. Chargement de l'assembly

Lorsque le compilateur JIT compile le code IL en code local, il vérifiera quels types sont référencés dans le code IL. Pendant l'exécution, le compilateur JIT utilise les tables de métadonnées TypeRef et AssemblyRef de l'assembly pour déterminer quel assembly définit le type référencé. Le compilateur JIT charge ensuite l'assembly correspondant dans AppDomain. En interne, le CLR utilise System La méthode statique Load de .Reflection. La classe Assembly tente de charger un assembly. Cependant, si nous souhaitons charger dynamiquement un assembly, nous pouvons utiliser la méthode Load de Assembly pour charger dynamiquement l'assembly. La classe Assembly fournit également d'autres méthodes de chargement d'assembly, notamment LoadFrom (string path), LoadFile (stringassemblyFile), etc.

2. Mécanisme de réflexion

Dans .net, la réflexion analyse les métadonnées de l'assembly pendant l'exécution et obtient des informations sur les membres du type (y compris les champs, les constructeurs, les méthodes, les propriétés, les événements, etc.).

Charger dynamiquement un assembly et obtenir les membres du type

Placez la classe suivante dans un projet de bibliothèque de classes, puis compilez et générez l'assembly (par exemple, ClassLibrary1.dll, en supposant que la dll est placée sous le répertoire racine de le lecteur 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 ";        }    }

Créez ensuite un programme console pour charger dynamiquement l'assembly généré ci-dessus et les membres du type de sortie. L'introduction détaillée se trouve dans le 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();         }     }

Filtrer les types de membres renvoyés

Vous pouvez appeler la méthode GetMembers, GetFields, GetMethods, GetProperties ou GetEvenents de Type pour interroger les membres d'un type. Lorsque vous appelez l'une des méthodes ci-dessus, vous pouvez transmettre une instance du type d'énumération System.Reflection.BindingFlags. Le but de l'utilisation de ce type d'énumération est de filtrer les membres renvoyés par ces méthodes.

Remarque : parmi toutes les méthodes qui renvoient une collection de membres, il existe une version surchargée qui n'obtient aucun paramètre réel. Si le paramètre réel BindingFlags n'est pas transmis, toutes ces méthodes renvoient des membres publics et le paramètre par défaut est BindingFlags.Public|BindingFlags.Instance|BindingFlags.Static (si Public ou NonPublic est spécifié, Instance doit être spécifié en même temps, sinon aucun membre ne sera renvoyé).

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer