Java之反射小结

反射概念

java文件在编译后会变成.class文件,本身是.java,在镜中是.class,他们其实是一样的。我们看到镜子的反射是.class,就能通过反编译,了解到.java文件的本来面目。Java反射允许程序在运行时来进行自我检查并且对内部的成员进行操作。

它允许一个Java类获取它所有的成员变量和方法并且显示出来。反射主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

在Java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。这也是Java被视为动态语言的一个关键性质。

反射用途

我们知道反射机制允许程序在运行时取得任何一个已知名称的class的内部信息,包括包括其modifiers(修饰符),fields(属性),methods(方法)等,并可于运行时改变fields内容或调用methods。可以更灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码链接,降低代码的耦合度;还有动态代理的实现等等。但是需要注意的是反射使用不当会造成很高的资源消耗

三种获取Class对象方法

public static void main(String[] args) {
	//第一种方式获取Class对象
	User user = new USer();//这一new 产生一个User对象,一个Class对象。
	Class userClass = user.getClass();//获取Class对象
	System.out.println(userClass.getName());
	
	//第二种方式获取Class对象
	Class userClass2 = User.class;
	System.out.println(userClass == userClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
	
	//第三种方式获取Class对象
	try {
		Class userClass3 = Class.forName("fanshe.User");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
		System.out.println(userClass3 == userClass2);//判断三种方式是否获取的是同一个Class对象
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	}
}

一些class方法

/*
 *得到某个对象的属性
 */
public Object getProperty(Object owner, String fieldName) throws Exception {  
     //得到该对象的Class
     Class ownerClass = owner.getClass();  
	 
	 //通过Class得到类声明的属性
     Field field = ownerClass.getField(fieldName); 
	 
	 //通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException。
     Object property = field.get(owner);
	 return property;  
}  
	 
/*
 *得到某个类的静态属性
 */
public Object getStaticProperty(String className, String fieldName)throws Exception {  
     //得到这个类的Class
     Class ownerClass = Class.forName(className);
	 
     //和上面一样,通过Class得到类声明的属性
     Field field = ownerClass.getField(fieldName);
	 
     //这里和上面有些不同,因为该属性是静态的,所以直接从类的Class里取
     Object property = field.get(ownerClass);
     return property;  
}

/*
 *执行某对象的方法
 */
public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception { 
     //得到这个对象的Class
     Class ownerClass = owner.getClass(); 
	 
     //配置参数的Class数组,作为寻找Method的条件
     Class[] argsClass = new Class[args.length];
     for (int i = 0, j = args.length; i < j; i++){
         argsClass[i] = args[i].getClass();
     }
	 
     //通过methodName和参数的argsClass(方法中的参数类型集合)数组得到要执行的Method
     Method method = ownerClass.getMethod(methodName,argsClass);  
	 
     //执行这个方法。owner对象中带有参数args的method方法。返回值是Object,也既是该方法的返回值
     return method.invoke(owner, args);  
}  

/*
 *执行某个类的静态方法
 */
public Object invokeStaticMethod(String className, String methodName, Object[] args) throws Exception {  
     //得到这个对象的Class
	 Class ownerClass = Class.forName(className);  
     
	 //配置参数的Class数组,作为寻找Method的条件
     Class[] argsClass = new Class[args.length];  
     for (int i = 0, j = args.length; i < j; i++) {  
         argsClass[i] = args[i].getClass();  
     }  
     //通过methodName和参数的argsClass(方法中的参数类型集合)数组得到要执行的Method
     Method method = ownerClass.getMethod(methodName,argsClass);  
     //这是静态方法,不需要借助实例运行。执行参数数组args的invoke()方法。
     return method.invoke(null, args);  
}

/*
 *新建实例
 */
public Object newInstance(String className, Object[] args) throws Exception {  
     //得到要构造的实例的Class
	 Class newoneClass = Class.forName(className);
     
	 //得到参数的Class数组
     Class[] argsClass = new Class[args.length];
     for (int i = 0, j = args.length; i < j; i++) {
         argsClass[i] = args[i].getClass();
     }
	 
     //得到构造子
     Constructor cons = newoneClass.getConstructor(argsClass);
	 
     //执行带参数的构造函数来新建实例的方法。如果不需要参数,可以直接使用
     return cons.newInstance(args);
}  

/*
 *判断是否为某个类的实例
 */
public boolean isInstance(Object obj, Class cls) { 
     return cls.isInstance(obj);
}  

/*
 *得到数组中的某个元素
 */
public Object getByArray(Object array, int index) {
     return Array.get(array,index);
} 

猜你喜欢

转载自blog.csdn.net/weixin_42679286/article/details/87525826
今日推荐