【JAVA与C#比较】反射

1.反射方面,java通常通过Class对象,获取方法、字段等信息,Class是Type接口的实现类。而C#是通过Type获取。
Class<Test> cal = Test.class;
//获取带两个参数的replace方法
Method replace = cal.getMethod("replace",String.class,List.class);
Type t = typeof(double);
MethodInfo[] methods = t.GetMethods();

2.java中可以使用Class对象的newInstance方法来创建该Class对象对应类的实例,实际上是利用默认构造器来创建的。而C#中用Assembly对象或Activator对象的CreateInstance方法来实现。
Class<?> cal = Class.forName(calName);          //类名称作为参数生成对应类对象
Object class = cal.newInstance();
Assembly cal = Assembly.LoadFile("dllfilepath");//dll文件路径生成Assembly对象
object class = cal.CreateInstance("classpath"); //参数为命名空间名称.类名称
object class2 = Activator.CreateInstance(targetType)//参数为对象类的类型

3.值得注意的共同点是,通过反射创建对象时性能要稍低一些,只有当程序需要动态创建某个类的对象时,才会考虑使用反射,通常在开发通用性比较广的框架、基础平台时可能会大量使用反射。还有就是两者方法使用相差不大,不管是获取对象信息,还是调用对象内部信息或方法。


4.java中若想反射调用private成员,需要先调用setAccessible方法,取消java语言的访问权限检查。而C#是通过设置变量绑定类型来实现。
Person p = new Person();
Class<Person> cal = Person.class; 
Field nameField = cal.getDeclareField("name");
nameField.setAccessible(true);   //设置反射访问此成员变量时取消权限检查
nameField.set(p,"Yeeku.H.Lee");
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic; //设置成员变量绑定类型为实例非共有
Type type = instance.GetType(); 
FieldInfo field = type.GetField("name", flag); 
field.SetValue(instance, value); 


5.java中使用getType方法只能获得普通类型的成员变量的数据类型,对于增加了泛型的成员变量,应使用getGenericType方法来获取其类型,之后才能通过getActualTypeArguments方法获取泛型类型里面的泛型参数。但如果泛型参数本身就是类的话,java不方便继续获取参数类里面的内容了。而C#可以通过参数类型里面的PropertyType类型,继续获取该参数类型里面的内容。
public class Test {
	private List<Tese> score;
	/**
	 * @param args
	 * @throws NoSuchFieldException 
	 * @throws SecurityException 
	 */
	public static void main(String[] args) throws SecurityException, NoSuchFieldException {
		Class<Test> cal = Test.class;
		Field f = cal.getDeclaredField("score");
		Class<?> a = f.getType();  //直接getType获取类型只对普通类型的成员变量有效,a此时为interface java.util.Map
		Type gType = f.getGenericType(); //获得成员变量f的泛型类型;
		if(gType instanceof ParameterizedType){ //如果是ParameterizedType对象
		    ParameterizedType pType = (ParameterizedType)gType;//强制类型转换
		    Type rType = pType.getRawType();//获取原始类型interface java.util.Map
		    System.out.println(rType);
		    Type[] tArgs = pType.getActualTypeArguments();//取得泛型类型的泛型参数
		    //只能强制类型转换后来去的真正的参数类型,这需要本身就知道其类型才能强制转换,因为从tArgs[0]无法获取到其真正类型的信息(为啥编译器可以获取到name,但代码取不到?)
		    Class<Test> entityClass = (Class<Test>)tArgs[0];
		    Field f2 = entityClass.getDeclaredField("fdname"); //取得该字段
		    System.out.println(tArgs[0]+"");//class Tese
		}
	}
}

public class Tese {
    private String fd = "123";
    private int fdname = 456;
}


猜你喜欢

转载自blog.csdn.net/u014650759/article/details/79547495