`

Java反射常用机制

    博客分类:
  • Java
 
阅读更多

首先要求大家对Java泛型知识有所了解,因为程序代码中大量使用了泛型相关知识。

 

  • 动态语言与反射
“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
  • Java反射的典型应用
Spring框架:IOC(控制反转)、白盒测试、Hibernate框架:关联映射等
  • Java反射常用的对象
java.lang包下Class<T>:表示一个正在运行的 Java 应用程序中的类和接口,是Reflection的起源;
java.lang.reflect包下Field 类:代表类的成员变量(也称类的属性)、Method类:代表类的方法、Constructor 类:代表类的构造方法、Array类:提供了动态创建数组,以及访问数组的元素的静态方法。
 
  • Class<T>

 

类是程序的一部分,每个类都有一个Class对象。换言之,每当编写并且编译了一个新类,就会产生一个Class对象。

Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。

Class是Reflection起源。要想操纵类中的属性和方法,都必须从获取Class object开始。

 

第一个实例就用大家非常熟悉的ArrayList类,我们尝试来获取ArrayList申明的方法。

 

public static void main(String[] args) {
	ArrayList aList = new ArrayList(); 
	Class alClass = aList.getClass();
	System.out.println("①"+alClass);
	System.out.println("②"+alClass.getName());
	Method[] alMethod = alClass.getDeclaredMethods();
	for(Method method : alMethod){
		System.out.println("③"+method);
		System.out.println("④"+method.getName());
	}
}

 

 


 

 

 

 

获取Class对象的方法
获取方法 说明 示例
object.getClass()每个对象都有此方法 获取指定对象的Class

List list = new ArrayList();

Class listClass = list.getClass();

class. getSuperclass() 获取当前Class的继承类Class

List list = new ArrayList();

Class listClass = list.getClass();

Class superClass = listClass. getSuperclass();

Object.class .class直接获取 Class listClass = ArrayList.class;
Class.forName(类名) 用Class的静态方法,传入类的全称即可 Class c = Class.forName("java.util.ArrayList");
Primitive.TYPE 基本数据类型的封装类获取Class的方式

Class longClass = Long.TYPE;

Class integerClass = Integer.TYPE;

Class voidClass = Void.TYPE;

 

 
平常情况我们通过new Object来生成一个类的实例,但有时候我们没法直接new,只能通过反射动态生成。
实例化无参构造函数的对象,两种方式:
Class. newInstance();
Class. getConstructor (new Class[]{}).newInstance(new Object[]{})
 实例化带参构造函数的对象:
clazz. getConstructor(Class<?>... parameterTypes) . newInstance(Object... initargs) 
 
首先我们新建一个JavaBean—User,User继承自另一个Bean—BaseUser。注意:这两个Bean的属性和方法的作用域!



 
 下面看代码实例:


 
 
  • Method对象--反射方法
获得当前类以及超类的public Method:
Method[] arrMethods = classType. getMethods();
 
获得当前类申明的所有Method:
Method[] arrMethods = classType. getDeclaredMethods();
 
获得当前类以及超类指定的public Method:
Method method = classType. getMethod(String name, Class<?>... parameterTypes);
 
获得当前类申明的指定的Method:
Method method = classType. getDeclaredMethod(String name, Class<?>... parameterTypes) ;
 
通过反射动态运行指定Method:
Object obj = method. invoke(Object obj, Object... args);
 
下面看代码实例:


 


 

 
  • Field 对象--反射属性
获得当前类以及超类的public Field:
Field[] arrFields = classType. getFields();
 
获得当前类申明的所有Field:
Field[] arrFields = classType. getDeclaredFields();
 
获得当前类以及超类指定的public Field:
Field field = classType. getField(String name);
 
获得当前类申明的指定的Field:
Field field = classType. getDeclaredField(String name); 
 
通过反射动态设定Field的值:
fieldType.set(Object obj, Object value);
 
通过反射动态获取Field的值: 
Object obj = fieldType. get(Object obj) ;
 
 
下面是具体的代码实例:


 


 

 
  • Spring框架的IOC的简化实现


 


 

 

  • Java反射总结

只要用到反射,先获得Class Object

 

没有方法能获得当前类的超类的private方法和属性,你必须通过getSuperclass()找到超类以后再去尝试获得

 

通常情况即使是当前类,private属性或方法也是不能访问的,你需要设置setAccessible(true)(取消访问安全校验)来取得private的访问权。根据《编写高质量代码:改善Java程序的151个建议》书中介绍,除非一定要控制private安全访问,否则反射时都取消Java的安全访问校验(即设置setAccessible(true)),这样能提高反射性能。

 

Array对象并未讲解,请下来自己学习

  • 大小: 61.9 KB
  • 大小: 9.8 KB
  • 大小: 20.7 KB
  • 大小: 99.5 KB
  • 大小: 70.2 KB
  • 大小: 108 KB
  • 大小: 50.2 KB
  • 大小: 32.4 KB
  • 大小: 81.8 KB
  • 大小: 10 KB
1
1
分享到:
评论
3 楼 xjlcao 2013-01-05  
想请教一下,如果BaseUser类里面有ArrayList属性呢,该怎么反射呢?
2 楼 白糖_ 2012-08-06  
sweat89 写道
设置压制权限setAccessible(true)来取得 private的访问权?
楼主能具体讲解下怎么获取private修饰的方法么


用getDeclaredMethod就可以获取当前类的private方法了,然后再setAccessible(true)就可以调用运行该方法
Method method = classType. getDeclaredMethod(String name, Class<?>... parameterTypes) ;
1 楼 sweat89 2012-08-05  
设置压制权限setAccessible(true)来取得 private的访问权?
楼主能具体讲解下怎么获取private修饰的方法么

相关推荐

Global site tag (gtag.js) - Google Analytics