java反射机制
2015-08-03 16:25
447 查看
Java反射机制
本节所有目录如下:
Java反射机制容许程序在运行时加载、探知、使用编译期间完全未知的classes。换言之,Java可以加载一个运行时才得知名称的class,获得其完整结构。
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判段任意一个类所具有的成员变量和方法
在运行时调用任一个对象的方法
在运行时创建新类对象
在使用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<T>类提供了几个方法获取类的属性。
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);
}
Class<T>类提供了几个方法获取类的方法。
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);
}
Class<T>类提供了几个方法获取类的构造器。
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反射的应用
本节所有目录如下:
什么是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 对象所表示的类或接 口所声明的所有字段 |
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 对象表示的类或接口声明的 所有方法,包括公共、保护、默认(包) 访问和私有方法,但不包括继承的方法 |
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反射的应用
相关文章推荐
- java小结
- java多线程同步
- Leetcode-8(Java) String to Integer (atoi)
- java多线程--障碍器
- springMail发送Text简单邮件的方法
- Java byte数组 转short int
- java可变参数
- C # 和 Java的不同之处
- spring 自动检测bean
- java容器上
- Spring总结
- JAVA内存管理
- 重学java23种设计模式(9)装饰者模式
- Spring源码学习-4.IoC.依赖注入
- java.util.concurrent.atomic原理详解
- Java NIO系列教程(九) Java NIO与BIO
- Java NIO系列教程(八) FileChannel
- Java NIO系列教程(七) DatagramChannel
- SpringMVC + Spring 3.2.14 + Hibernate 3.6.10 集成详解
- Java NIO系列教程(六) ServerSocketChannel