JAVA的反射机制简介(上)

来源:互联网 发布:哪里有专业的java培训 编辑:程序博客网 时间:2024/06/06 10:57
本文参照整理自己:http://www.cnblogs.com/Quincy/archive/2011/06/19/2084557.html
一、什么是JAVA的反射机制
  Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fieldsmethods的所有信息,并可于运行时改变fields内容或调用methods
Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的classes。换言之,Java可以加载一个运行时才得知名称的class,获得其完整结构。
二、JDK中提供的Reflection API
Java反射相关的API在包java.lang.reflect中,JDK 1.6.0的reflect包如下图:
JAVA的反射机制简介 - hubingforever - 民主与科学
 
Member接口该接口声明了获取类的成员(类的成员包括域,方法,构造函数)的信息基本方法。Constructor<T>, Field, Method类都实行了该接口AccessibleObject类该类是field类(域)、method类(对象)、constructor类(构造函数)的父亲类。它提供了对类的成员进行访问控制的能力。比如对private的成员,外部类就不对他们进行访问,AccessibleObject此时应该抛出IllegalAccessException异常Array类该类提供动态地生成和访问类的数组型成员的方法。Constructor类它对应于类的构造函数,提供对类的构造函数进行访问的接口。Field类它对应于类的成员变量(域),提供了对类的成员变量(域)进行访问的接口。Method类它对应于类的方法,提供了对类的方法进行调用和访问的接口。Modifier类它对应于类的成员的修饰符,提供了对修饰符进行访问的接口。Proxy类

提供动态地生成代理类和类实例的静态方法。

三、JAVA反射机制提供了什么功能
Java反射机制提供如下功能:
1、在运行时判断任意一个对象所属的类
2、在运行时构造任意一个类的对象
3、在运行时判段任意一个类所具有的成员变量和方法
4、在运行时调用任一个对象的方法
5、在运行时创建新类对象
在使用Java的反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他的对象。
3.1、如何获取类的Class对象
Class类的实例表示一个已经装载的Class(包括Interface)。获取类的Class对象有多种方式:
在对象上直接调用getClass方法

Boolean var1 = true;

Class<?> classType2 = var1.getClass();

System.out.println(classType2);

输出:class java.lang.Boolean

运用.class 语法

Class<?> classType4 = Boolean.class;

System.out.println(classType4);

输出:class java.lang.Boolean

运用static method Class.forName()

Class<?> classType5 = Class.forName("java.lang.Boolean");

System.out.println(classType5);

输出:class java.lang.Boolean

运用primitive wrapper classes的TYPE 语法

这里返回的是原生类型,和Boolean.class返回的不同

Class<?> classType3 = Boolean.TYPE;

System.out.println(classType3);        

输出:boolean

3.2、如何获取类的Fields
可以通过反射机制可以得到某个类的某个属性(Fields),然后可以改变对应于这个类的某个实例的该属性值。JAVA 的Class<T>类提供了几个方法获取类的属性。
public Field getField(String name)返回一个 Field 对象,它反映此 Class 对象所表示的类或接口(包括父亲类及implements接口)的指定公共(public)成员字段public Field[] getFields()返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的(包括父亲类及implements接口)所有可访问公共(public)字段public Field getDeclaredField(Stringname)返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口(不包括父亲类和implements接口)的指定已声明字段,包括修饰符为publicprotected,private默认包级的字段public Field[] getDeclaredFields()

返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口(不包括父亲类和implements接口)所声明的所有字段,包括修饰符为publicprotected,private默认(包)的字段。

3、获取类的Method
可以通过反射机制得到某个类的某个方法,然后调用对应于这个类的某个实例的该方法
Class<T>类提供了几个方法获取类的方法。
public Method getMethod(String name,Class<?>... parameterTypes)

返回一个 Method 对象,它反映此 Class 对象所表示的类或接口和(包括父亲类及父亲类implements的接口和自己实现的接口)的指定公共(public)成员方法

public Method[] getMethods()

返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口和自己实现的接口)的公共(public) 成员方法

public Method getDeclaredMethod(Stringname,Class<?>... parameterTypes)

返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的(不包括父亲类和父亲类implements的接口,但包括自己实现的接口指定已声明方法,,包括修饰符为publicprotected,private默认包级的方法

public Method[] getDeclaredMethods()

返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口(不包括父亲类和父亲类implements的接口,但包括自己实现的接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法

3.4、获取类的Constructor
可以通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例 
Class<T>类提供了几个方法获取类的构造器。
public Constructor<T> getConstructor(Class<?>... parameterTypes)

返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共public)构造方法

public Constructor<?>[] getConstructors()

返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共(public)构造方法

public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)

返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法

public Constructor<?>[] getDeclaredConstructors()

返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。它包括所有公共、保护、默认(包)访问和私有构造方法

3.5、新建类的实例
可以通过反射机制创建新类的实例,有几种方法可以创建
调用无自变量ctor

1、调用类的Class对象的newInstance方法,该方法会调用对象的默认构造器,如果没有默认构造器,会调用失败.

Class<?> classType = ExtendType.class;

Object inst = classType.newInstance();

System.out.println(inst);

输出:

Type:Default Constructor

ExtendType:Default Constructor

com.quincy.ExtendType@d80be3

 

2、调用默认Constructor对象的newInstance方法

Class<?> classType = ExtendType.class;

Constructor<?> constructor1 = classType.getConstructor();

Object inst = constructor1.newInstance();

System.out.println(inst);

输出:

Type:Default Constructor

ExtendType:Default Constructor

com.quincy.ExtendType@1006d75

调用带参数ctor

3、调用带参数Constructor对象的newInstance方法

Constructor<?> constructor2 =

classType.getDeclaredConstructor(int.class, String.class);

Object inst = constructor2.newInstance(1, "123");

System.out.println(inst);

输出:

Type:Default Constructor

ExtendType:Constructor with parameters

com.quincy.ExtendType@15e83f9

java.lang.reflect.Modifier用于表示Field或Method的修饰,通过他们的getModifiers()方法可以取得。
其方法摘要如下:
方法摘要static booleanisAbstract(int mod) 
          如果整数参数包括 abstract 修饰符,则返回 true,否则返回 falsestatic booleanisFinal(int mod) 
          如果整数参数包括 final 修饰符,则返回 true,否则返回 falsestatic booleanisInterface(int mod) 
          如果整数参数包括 interface 修饰符,则返回 true,否则返回 falsestatic booleanisNative(int mod) 
          如果整数参数包括 native 修饰符,则返回 true,否则返回 falsestatic booleanisPrivate(int mod) 
          如果整数参数包括 private 修饰符,则返回 true,否则返回 falsestatic booleanisProtected(int mod) 
          如果整数参数包括 protected 修饰符,则返回 true,否则返回 falsestatic booleanisPublic(int mod) 
          如果整数参数包括 public 修饰符,则返回 true,否则返回 falsestatic booleanisStatic(int mod) 
          如果整数参数包括 static 修饰符,则返回 true,否则返回 falsestatic booleanisStrict(int mod) 
          如果整数参数包括 strictfp 修饰符,则返回 true,否则返回 falsestatic booleanisSynchronized(int mod) 
          如果整数参数包括 synchronized 修饰符,则返回 true,否则返回 falsestatic booleanisTransient(int mod) 
          如果整数参数包括 transient 修饰符,则返回 true,否则返回 falsestatic booleanisVolatile(int mod) 
          如果整数参数包括 volatile 修饰符,则返回 true,否则返回 falsestatic StringtoString(int mod) 
          返回描述指定修饰符中的访问修饰符标志的字符串。
关于JAVA反射机制的使用示例请阅读《JAVA的反射机制简介(下)》
原创粉丝点击