一.JAVA中的反射
需要导入包:import java.lang.reflect;
try {
//加载类的三种方法
// Class< ?> classType = Class.forName("com.ls.reflecttest.Person");
// Class< ?> classType = Person.class;
Class< ?> classType = Person.getClass();
//创建对象,第一种方法只能调用默认的构造方法,第二种方法可以调用带参的构造方法
// Object object = classType.newInstance();
Object object = classType.getConstructor(new Class[] {int.class, String.class, int.class}).newInstance(new Object[] {12, "wdw", 12});
//动态得到该对象的方法
Method sayHelloMethod = classType.getMethod("sayHello", new Class[]{String.class});
sayHelloMethod.invoke(object, new Object[] {"wdw"});
//动态得到所有属性,
Field[] filds = classType.getDeclaredFields();
for(int i=0; i < filds.length; i++) {
System.out.println(filds[i].getName());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
此外还有很多方法:得到所有方法getDeclaredMethods(), getField()等等
二.C#中的反射
感觉跟JAVA中的反射机制是一样的,首先引入命名空间:using System.reflection;
//得到该类型所在的程序集
Assembly assembly = Assembly.GetAssembly(type);//类似于JAVA中的加载
//C#中可以直接加载文件
//Assembly assembly = Assembly.LoadFile("文件路径"); //JAVA中没有这种方法
//创建对象
Object o = assembly.CreateInstance("ReflectTest.Person");
//动态获得方法
MethodInfo method = type.GetMethod("ToString");
//调用方法
Console.WriteLine(method.Invoke(o, new object[] { }));
--------------------------------------------------------------------
//得到类型
反射的核心Type类,Type对象提供的属性和方法可以获取对象的一切信息,如:方法、字段、属性、事件...等等。
Type type = Type.GetType("ReflectTest.Person");
(以StringBuilder 类型为例)
- 直接使用typeof操作符 Type T1 = typeof(StringBuilder);
- 通过类型实例 Type T2 = new StringBuilder().GetType();
- 通过Type类的静态方法 Type T3 = Type.GetType("System.IO.Stream");
根据type可以得到信息
获取类型本身信息(命名空间名、全名、是否是抽象、是否是类、、、等等)
var T1 = typeof(StringBuilder);
Console.WriteLine("命名空间名称:" + T1.Namespace);
Console.WriteLine("直接基类型:" + T1.BaseType);
Console.WriteLine("全名:" + T1.FullName);
Console.WriteLine("是抽象类型:" + T1.IsAbstract);
Console.WriteLine("是类:" + T1.IsClass);
//.....等等
获取类型成员信息(通过Tyep中的方法GetMembers)
Type T1 = typeof(TClass);
var Mets = T1.GetMembers();//获取Type对象的所有公有成员
foreach (var m in Mets)
{
Console.WriteLine("【" + m.MemberType.ToString()+ "】:" + m.Name);
// m.MemberType 是成员类型
}
动态调用方法
首先定义个类:
public class TClass
{
public void fun(string str)
{
Console.WriteLine("我是fun方法,我被调用了。" + str);
}
public void fun2()
{
Console.WriteLine("我是fun2方法,我被调用了。");
}
public static void fun3()
{
Console.WriteLine("我是fun3静态方法,我被调用了");
}
}
调用方式一(使用InvokeMember调用方法)
调用带参实例方法fun
Type T1 = typeof(TClass);
T1.InvokeMember("fun", BindingFlags.InvokeMethod, null, new TClass(), new string[] { "test" });
调用无参实例方法fun2
Type T1 = typeof(TClass);
T1.InvokeMember("fun2", BindingFlags.InvokeMethod, null, new TClass(), null);
调用静态方法
Type T1 = typeof(TClass);
T1.InvokeMember("fun3", BindingFlags.InvokeMethod, null, T1, null);
调用方式二(使用MethodInfo.Invoke调用方法)
Type T1 = typeof(TClass);
T1.GetMethod("fun", BindingFlags.Instance | BindingFlags.Public).Invoke(new TClass(), new string[] { "testfun1" });
T1.GetMethod("fun2", BindingFlags.Instance | BindingFlags.Public).Invoke(new TClass(), null);
T1.GetMethod("fun3", BindingFlags.Static | BindingFlags.Public).Invoke(T1, null);