>  기사  >  Java  >  Java의 어셈블리 로딩 및 리플렉션 메커니즘은 무엇입니까?

Java의 어셈블리 로딩 및 리플렉션 메커니즘은 무엇입니까?

王林
王林앞으로
2023-05-07 13:25:07688검색

1. 어셈블리 로딩

JIT 컴파일러는 IL 코드를 로컬 코드로 컴파일할 때 IL 코드에서 참조되는 유형을 확인합니다. 런타임 동안 JIT 컴파일러는 어셈블리의 TypeRef 및 AssemblyRef 메타데이터 테이블을 사용하여 참조된 형식을 정의하는 어셈블리를 결정합니다. 그런 다음 JIT 컴파일러는 내부적으로 .Reflection의 정적 메서드 Load를 사용합니다. Assembly 클래스가 어셈블리 로드를 시도합니다. 그러나 어셈블리를 동적으로 로드하려는 경우 Assembly의 Load 메서드를 사용하여 어셈블리를 동적으로 로드할 수 있습니다. Assembly 클래스는 LoadFrom(문자열 경로), LoadFile(stringassembleFile) 등을 포함한 다른 로드 어셈블리 메서드도 제공합니다.

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 실제 매개 변수가 전달되지 않으면 이러한 메서드는 모두 public 멤버를 반환하고 기본 설정은 BindingFlags.Public|BindingFlags.Instance|BindingFlags.Static입니다. (Public 또는 NonPublic을 지정한 경우 Instance를 동시에 지정해야 합니다. 그렇지 않으면 어떤 회원도 반환되지 않습니다.)

위 내용은 Java의 어셈블리 로딩 및 리플렉션 메커니즘은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제