Java反射机制的简单学习
今天看了一下Java的反射机制,就此记录一下。
首先,我们要先了解一下什么是反射?
- 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。
- JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
Java反射的应用
- Spring框架
- Hibernate框架:关联映射等
- 白盒测试
Java反射相关API
java.lang包下
-Class<T>:表示一个正在运行的 Java 应用程序中的类和接口,是Reflection的起源
java.lang.reflect包下
-Field 类:代表类的成员变量(也称类的属性)
-Method 类 : 代表类的方法
-Array 类 : 提供了动态创建数组,以及访问数组的元素的静态方法
反射的类类型:Class
假设我们有一个Role类
1 package _Venom_.reflection; 2 3 public class Role { 4 5 private String name; 6 private String type; 7 8 //Constructors 9 public Role(){ 10 System.out.println("Constructor Role() is invoking!"); 11 } 12 13 private Role(String _name){ 14 this.name = _name; 15 System.out.println("Constructor Role(String _name) is invoking!"); 16 } 17 18 19 //get and set method 20 public String getName() { 21 return name; 22 } 23 24 public void setName(String name) { 25 this.name = name; 26 } 27 28 public String getType() { 29 return type; 30 } 31 32 public void setType(String type) { 33 this.type = type; 34 } 35 36 //override the toString method to show the class 37 @Override 38 public String toString() { 39 // TODO Auto-generated method stub 40 return "This is a role called " + this.name; 41 } 42 43 }
我们可以通过以下方式得到类类型。
获取方式 |
说明 |
示例 |
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的静态方法,传入类的全称即可 |
try { Class c = Class.forName("java.util.ArrayList"); } catch (ClassNotFoundException e) { e.printStackTrace(); } |
Primitive.TYPE |
基本数据类型的封装类获取Class的方式 |
Class longClass = Long.TYPE; Class integerClass = Integer.TYPE; Class voidClass = Void.TYPE; |
Class class1 = Role.class; try { Class class2 = Class.forName("_Venom_.reflection.Role"); } catch (ClassNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }
通过类类型的newInstance方法来创建一个实例。如下
Object obj = class1.newInstance();
但是,我们通常的做法是通过Constructor类来获取类的构造方法,然后再通过Constructor类的newInstance方法来创建实例。
获取类的构造器
Constructor类:
- public Constructor<?>[] getConstructor() 返回类中的所有public构造器集合,默认构造器的下标为0
- public Constructor<T> getConstructor(Class<?>...parameterTypes) 返回指定的public构造器,参数为构造器参数类型集合
- public Constructor<?>[] getDeclaredConstructor() 返回类中所有的构造器,包括私有
- public Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes) 返回任意指定的构造器
Class class1 = Role.class; try { Class class2 = Class.forName("_Venom_.reflection.Role"); } catch (ClassNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } /** * 获取构造方法Constructor * getConstructor() only for public * getDeclaredConstructor() global access all * */ Constructor constructor = null; //指定参数列表获取特定的方法 try {
//1 constructor = class1.getDeclaredConstructor(new Class[]{String.class}); //设置可访问的权限 不设置会报IllegalAccessException异常 constructor.setAccessible(true); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } Object obj = null; try { obj = constructor.newInstance(new Object[]{"Venom"}); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } //打印对象的信息 System.out.println(obj); //2获取所有的构造方法的集合 Constructor constructorArr[] = null; constructorArr = class1.getDeclaredConstructors(); constructorArr[1].setAccessible(true); Object obj1 = null; try { obj1 = constructorArr[1].newInstance(new Object[]{"_Venom_"}); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(obj1);
在获取类的方法的时候,我们可以使用Method类:
总结:
感觉今天学习的Java反射机制还是很有用出的,以此Mark一下我的学习历程。