Java中的反射机制
- 一、反射机制之Class
- 1.获取Class
- 二、反射机制之Constructor
- 1.获取Constructor
- 2.使用Constructor实例化对象
- 三、实例化对象
- 四、反射机制之Method
- 1.获取Method
- 2.调用方法
- (1)调用私有方法
- (2)调用静态方法
- (3)调用可变参数方法
- 五、反射机制之Field
- 1.获取Field
- 2.使用Field
- 六、反射的应用案例
- 1.用反射来遍历对象中的属性
- JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
一、反射机制之Class
- 代表类的实体,在运行的Java应用程序中表示类和接口。
1.获取Class
- ① 类型.class
Class<User> userClass = User.class;
- ② Class.forName(“完整类名”)
- 这种方式类加载,静态代码块执行
Class userClass = Class.forName("User");
- ③ 任何对象.getClass()
//创建一个User对象 User user = new User("root", "123456"); Class<? extends User> userClass = user.getClass();
- 常用方法
getPackage();//获取类的包 getName();//获取类的完整路径名字 getSimpleName();//获取类的名字 getSuperclass();//获取当前类继承的父类的名字
二、反射机制之Constructor
- 代表类的构造方法。
1.获取Constructor
public Constructor<T> getConstructor(Class<?>... parameterTypes);//获得该类中与参数类型匹配的公有构造方法
public Constructor<?>[] getConstructors();//获得该类的所有公有构造方法
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes);//获得该类中与参数类型匹配的构造方法
public Constructor<T> getDeclaredConstructor();//获得该类所有构造方法
2.使用Constructor实例化对象
newInstance(Object... initargs);//根据传递的参数创建类的对象
三、实例化对象
- userClass.newInstance(),这种方式必须确保无参数构造方法存在。
- userClass.getDeclaredConstructor().newInstance()
四、反射机制之Method
- 代表类的方法
1.获取Method
- 要获取方法
Method
,首先你需要获取这个类Class
。 - 当拿到
Class
之后,调用Class
的方法可以获取到对象的方法。- 获取一个方法,需要告诉Java程序,你要获取的方法名字是什么,这个方法上每个形参的类型是什么。这样Java程序才能给你拿到对应的方法。
- 这样的设计也非常合理,因为一个类当中,方法是支持重载的,也就说方法名可以一样,但参数列表一定是不一样的,所以获取一个方法需要提供方法名以及每个形参的类型。
/** * 四个方法中,不带Declared的方法能获取自身类和父类的所有public方法。带Declared的方法能获取自身所有方法但不能获取父类中的方法。 * 只有通过方法签名才能找到唯一的方法,方法签名=方法名+参数列表(参数类型、参数个数、参数顺序)。 * 只能获取父类中的public方法,无法获取到父类的默认权限和private权限方法 */ public Method getDeclaredMethod(String name, Class<?>... parameterTypes);//表示调用指定的一个本类中的方法(不包括继承的) public Method[] getDeclaredMethods();//获取自身所有的方法(不包括继承的和访问权限无关)。 public Method[] getMethods();//获取包括自身和继承过来的所有的public方法。 public Method getMethod(String methodName, Class<?>...parameterTypes);//表示调用指定的一个public方法(包括继承的)
2.调用方法
- 调用一个方法,一般涉及到四个要素:
- ① 调用哪个对象的。
- ② 哪个方法。
- ③ 传什么参数。
- ④ 返回什么值。
- 调用方法的三步骤:
- ① 创建对象(四要素之首:调用哪个对象的)
- ② 获取方法(四要素之一:哪个方法)
- ③ 调用方法
/**
* obj参数:表示调用方法底层所属对象。
* args参数:表示调用方法传递的实际参数。
* 返回值:底层方法的返回值。
*/
public Object invoke(Object obj, Object... args);//表示调用当前Method表示的方法。
(1)调用私有方法
- 在调用私有方法之前:应该设置该方法为可访问的。
- 因为
Method
是AccessibleObject
的子类,所以Method
中具有方法:setAccessible(true)
。
(2)调用静态方法
- 如果底层是静态方法,那么可以忽略指定的 obj 参数。将 obj 参数设置为 null 即可。
- 也可以将 obj 参数写上也没有影响。
(3)调用可变参数方法
-
对于数组类型的引用类型的参数,底层会自动解包,为了解决该问题,我们使用 Object 的一维数组把实际参数包装起来。
method.invoke(null, new Object[]{"username", "password"});
-
(牢记)以后使用反射调用
invoke
方法,在传递实际参数的时候,无论是基本数据类型还是引用数据类型,也无论是可变参数类型,反正就是一切实际参数都包装在new Object[]{}
中,就没问题。
五、反射机制之Field
- 代表类的成员变量(成员变量也称为类的属性)。
1.获取Field
public Field getDeclaredField(String name);//表示调用指定的一个本类中的属性(不包括继承的)
public Field[] getDeclaredFields();//获取自身所有的属性(不包括继承的和访问权限无关)。
public Field[] getFields();//获取包括自身和继承过来的所有的public属性。
public Field getField(String name);//表示调用指定的一个public属性(包括继承的)
2.使用Field
public void set(Object obj, Object value);//设置obj中对应属性值
public Object get(Object obj);//获得obj中对应的属性值
public boolean equals(Object obj);//属性与obj相等则返回true
六、反射的应用案例
1.用反射来遍历对象中的属性
- 使用反射来进行遍历对象中的所有属性名和属性值。在遍历中编写逻辑来对属性进行操作。
public static void main(String[]args) throws Exception {//创建一个User对象User user = new User("root", "123456");//通过getDeclaredFields()方法获取对象类中的所有属性(含私有)Field[] fields = user.getClass().getDeclaredFields();//遍历属性for (Field field : fields) {//通过setAccessible()设置为true,允许通过反射访问私有变量field.setAccessible(true);//获取属性值Object value = field.get(user);//获取属性名String name = field.getName();//输出到控制台System.out.println("属性名:"+name+" 值:"+value);// 其他操作...}
}
这个兄弟写的挺好可以参考 ===> Java反射的原理及反射创建类实例的三种方式