您的位置:首页 > 编程语言 > Java开发

java反射机制

2015-08-03 16:25 447 查看
Java反射机制
本节所有目录如下:

什么是JAVA的反射机制

Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。
Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的classes。换言之,Java可以加载一个运行时才得知名称的class,获得其完整结构。

JDK中提供的Reflection API

Java反射相关的API在包java.lang.reflect中:
Member接口
该接口可以获取有关类成员(域或者方法)后者构造函数的信息。
AccessibleObject类
该类是域(field)对象、方法(method)对象、构造函数(constructor)对象的基础类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。
Array类
该类提供动态地生成和访问JAVA数组的方法。
Constructor类
提供一个类的构造函数的信息以及访问类的构造函数的接口。
Field类
提供一个类的域的信息以及访问类的域的接口。
Method类
提供一个类的方法的信息以及访问类的方法的接口。
Modifier类
提供了 static 方法和常量,对类和成员访问修饰符进行解码。
Proxy类
提供动态地生成代理类和类实例的静态方法。

JAVA反射机制提供了什么功能

Java反射机制提供如下功能:

在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判段任意一个类所具有的成员变量和方法
在运行时调用任一个对象的方法
在运行时创建新类对象
在使用Java的反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他的对象。
这里首先定义用于测试的类:

1. class Type{
2. public int pubIntField;
3. public String pubStringField;
4. private int prvIntField;
5.
6. public Type(){
7. Log("Default Constructor");
8. }
9.
10. Type(int arg1, String arg2){
11. pubIntField = arg1;
12. pubStringField = arg2;
13.
14. Log("Constructor with parameters");
15. }
16.
17. public void setIntField(int val) {
18. this.prvIntField = val;
19. }
20. public int getIntField() {
21. return prvIntField;
22. }
23.
24. private void Log(String msg){
25. System.out.println("Type:" + msg);
26. }
27. }
28.
29. class ExtendType extends Type{
30. public int pubIntExtendField;
31. public String pubStringExtendField;
32. private int prvIntExtendField;
33.
34. public ExtendType(){
35. Log("Default Constructor");
36. }
37.
38. ExtendType(int arg1, String arg2){
39. pubIntExtendField = arg1;
40. pubStringExtendField = arg2;
41.
42. Log("Constructor with parameters");
43. }
44.
45. public void setIntExtendField(int field7) {
46. this.prvIntExtendField = field7;
47. }
48. public int getIntExtendField() {
49. return prvIntExtendField;
50. }
51.
52. private void Log(String msg){
53. System.out.println("ExtendType:" + msg);
54. }
55. }

获取类的Class对象

Class 类的实例表示正在运行的 Java
应用程序中的类和接口。获取类的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);
输出:boolea

获取类的Fields

可以通过反射机制得到某个类的某个属性,然后改变对应于这个类的某个实例的该属性值。JAVA
的Class<T>类提供了几个方法获取类的属性。
public Field getField(String name)
返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共
成员字段
public Field[] getFields()
返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示
的类或接口的所有可访问公共字段
public Field getDeclaredField(Stringname)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定
已声明字段
public Field[] getDeclaredFields()
返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接
口所声明的所有字段
Field
f = chinese.getField("name");//public 属性
Fieldf2 =
chinese.getDeclaredField("age");//private 属性
Field[]fs=
chinese.getFields();
Field[]fs2=
chinese.getDeclaredFields();

System.out.println(f);
System.out.println(f2);

for(Field
field:fs2) {
System.out.println(field);
}

获取类的Method

通过反射机制得到某个类的某个方法,然后调用对应于这个类的某个实例的该方法
Class<T>类提供了几个方法获取类的方法。
public Method getMethod(String name,Class<?>...
parameterTypes)
返回一个 Method 对象,它反映此 Class
对象所表示的类或接口的指定公共成员方法
public Method[] getMethods()
返回一个包含某些 Method 对象的数组,
这些对象反映此 Class 对象所表示的类或
接口(包括那些由该类或接口声明的以及从
超类和超接口继承的那些的类或接口)的
公共 member 方法
public MethodgetDeclaredMethod(Stringname,Class<?>...
parameterTypes)
返回一个 Method 对象,该对象反映此
Class 对象所表示的类或接口的指定已声明
方法
public Method[] getDeclaredMethods()
返回 Method 对象的一个数组,这些对象
反映此 Class 对象表示的类或接口声明的
所有方法,包括公共、保护、默认(包)
访问和私有方法,但不包括继承的方法
Method m = chinese.getMethod("walk");//公有方法名
Methodm2= chinese.getDeclaredMethod("say");//私有方法名
Method[]ms =
chinese.getDeclaredMethods();
Method[]ms2=
chinese.getDeclaredMethods();

System.out.println(m);

for(Method
method : ms) {
System.out.println(method);
}

获取类的Constructor

通过反射机制得到某个类的构造器,然后调用该构造器创建该类的一个实例
Class<T>类提供了几个方法获取类的构造器。
public Constructor<T>
getConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的
指定公共构造方法
public Constructor<?>[] getConstructors()
返回一个包含某些 Constructor 对象的数组,这些对象反映此
Class 对象所表示的类的所有公共构造方法
public Constructor<T>
getDeclaredConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,该对象反映此 Class 对象所表示的
类或接口的指定构造方法
public Constructor<?>[] getDeclaredConstructors()
返回 Constructor 对象的一个数组,这些对象反映此 Class 对象
表示的类声明的所有构造方法。它们是公共、保护、默认(包)访
问和私有构造方法


Constructor[] cons=
chinese.getConstructors();
Constructor[]cons2=
chinese.getDeclaredConstructors();
Constructorcon=
chinese.getConstructor(String.class);
Constructorcon2=
chinese.getDeclaredConstructor(String.class,int.class);
Constructorcon3=
chinese.getConstructor(new Class[]{});

System.out.println("con: "+
con);
System.out.println("con2: "+
con2);
System.out.println("con3 "+
con3);
for(Constructor
c:cons2) {
System.out.println(c);
}
· 新建类的实例

Class<T>的函数newInstance

通过Constructor对象的方法newInstance
2. 调用类的函数

通过反射获取类Method对象,调用Field的Invoke方法调用函数。

[java] view plaincopy

1. Class<?> classType = ExtendType.class;
2. Object inst = classType.newInstance();
3. Method logMethod = classType.<strong>getDeclaredMethod</strong>("Log", String.class);
4. logMethod.invoke(inst, "test");
5.
6. 输出:
7. Type:Default Constructor
8. ExtendType:Default Constructor
9. <font color="#ff0000">Class com.quincy.ClassT can not access a member of class com.quincy.ExtendType with modifiers "private"</font>
10.
11. <font color="#ff0000">上面失败是由于没有权限调用private函数,这里需要设置Accessible为true;</font>
12. Class<?> classType = ExtendType.class;
13. Object inst = classType.newInstance();
14. Method logMethod = classType.getDeclaredMethod("Log", String.class);
15. <font color="#ff0000">logMethod.setAccessible(true);</font>
16. logMethod.invoke(inst, "test");

3.设置/获取类的属性值

通过反射获取类的Field对象,调用Field方法设置或获取值

[java] view plaincopy

1. Class<?> classType = ExtendType.class;
2. Object inst = classType.newInstance();
3. Field intField = classType.getField("pubIntExtendField");
4. intField.<strong>setInt</strong>(inst, 100);
5. int value = intField.<strong>getInt</strong>(inst);

4.动态创建代理类

动态代理源码分析
代理模式:代理模式的作用=为其他对象提供一种代理以控制对这个对象的访问。

代理模式的角色:

抽象角色:声明真实对象和代理对象的共同接口

代理角色:代理角色内部包含有真实对象的引用,从而可以操作真实对象。

真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。

5.JAVA反射Class<T>类型源代码分析
6.JAVA反射原理分析

Class文件结构

JVM加载类对象,对反射的支持
7。JAVA反射的应用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: