如何使用Java反射?(反射篇 二)

Java反射的核心是 java.lang.reflect 包,该包提供了一组类和接口,用于在运行时获取类的信息并操作类的成员,主要涉及的类包括 Class 、 Field 、 Method 和 Constructor 。

1. 获取字节码对象(Class)

有三种方式获取:

  • Class这个类里面的静态方法forName(“全类名”)(最常用)
  • 通过class属性获取
  • 通过对象获取字节码文件对象

示例:

	// 方式1:使用对象的 .class 属性
    MyClass obj1 = new MyClass();
    Class<?> clazz1 = obj1.getClass();

    // 方式2:使用类的 .class 属性
    Class<?> clazz2 = MyClass.class;

    // 方式3:使用 Class.forName() 方法
    //Class.forName("类的全类名"): 全类名 = 包名 + 类名
    Class<?> clazz3 = 	Class.forName("com.test.MyClass");

2. 获取构造方法对象(Constructor)

基本方法介绍

方法名 说明
Constructor[] getConstructors() 获得所有的构造(只能public修饰)
Constructor[] getDeclaredConstructors() 获得所有的构造(包含私有方法)
Constructor getConstructor(Class… parameterTypes) 获取指定构造(只能public修饰)
Constructor getDeclaredConstructor(Class… parameterTypes) 获取指定构造(包含私有方法)

示例:

//获取类对象
Class clazz = MyClass.class;

//所有构造方法
Constructor[] constructors1 = clazz.getConstructors();

//获取所有构造(带私有的)
Constructor[] constructors2 = clazz.getDeclaredConstructors();

//获取指定的空参构造
Constructor con1 = clazz.getConstructor();
//获取具有String和int参数的构造方法对象
Constructor con2 = clazz.getConstructor(String.class,int.class);

//获取指定的构造(所有构造方法都可以获取到)
Constructor con3 = clazz.getDeclaredConstructor();
Constructor con4 = clazz.getDeclaredConstructor(String.class);

3. 根据构造方法对象来创建类实例对象

关键方法:newInstance()

//获取类对象
Class clazz = Class.forName("com.test.MyClass");
//1.获取空参的构造方法对象
Constructor con1 = clazz.getConstructor();
//创建实例对象
MyClass instance1 = (MyClass) con1.newInstance();

//2.获取有参构造方法对象(所有)
Constructor con2 = clazz.getDeclaredConstructor(String.class, int.class);
//临时修改构造方法的访问权限(暴力反射)
con2.setAccessible(true);
//直接创建实例对象
MyClass instance2= (MyClass) con2.newInstance("zhangsan", 23);

4. 获取成员变量对象并操作

基本方法介绍

方法名 说明
Field[] getFields() 返回所有成员变量对象的数组(只能拿public的)
Field[] getDeclaredFields() 返回所有成员变量对象的数组,存在就能拿到(包含私有)
Field getField(String name) 返回单个成员变量对象(只能拿public的)
Field getDeclaredField(String name) 返回单个成员变量对象,存在就能拿到(包含私有)
void set(Object obj, Object value) 赋值
Object get(Object obj) 获取值

示例:

//原对象
MyClass obj=new MyClass("张三",18);
//类对象
Class clazz = Class.forName("com.test.MyClass");
//1. 获取所有成员变量的对象(Field对象)只能获取public修饰的
Field[] fields1 = clazz.getFields();
//2. 获取所有成员变量的对象
Field[] fields2 = clazz.getDeclaredFields();
//3.获取单个(根据名字)
Field field3 = clazz.getField("name");
//4. 获取单个成员变量(包括私有)
Field field4 = clazz.getDeclaredField("age");

//根据对象修改属性
field3.set(obj,"李四")
//获取新属性
String result = (String)field3.get(s);
System.out.println(result);

5. 获取成员方法对象和操作

基本方法介绍

方法名 说明
Method[] getMethods() 返回所有成员方法对象的数组(只能拿public的包含父类方法
Method[] getDeclaredMethods() 返回所有成员方法对象的数组,存在就能拿到(包括私有,只能是本类方法)
Method getMethod(String name, Class… parameterTypes) 返回单个成员方法对象(只能拿public的)
Method getDeclaredMethod(String name, Class… parameterTypes) 返回单个成员方法对象,存在就能拿到 (包括私有)
Object invoke(Object obj, Object… args) 根据对象运行方法

示例:

Class clazz = Class.forName("com.test.MyClass");
//可以获取**父类**中public修饰的方法
Method[] methods1 = clazz.getMethods();
//获取包含参数的
Method methods2 = clazz.getMethod("show",String.class);
//……其他类似

//执行操作
//原对象
MyClass obj=new MyClass();
//如果方法没有返回值,则不需要接收
String result = (String) methods2.invoke(obj, "hello java");
System.out.println(result);

上一篇:了解Java反射原理

你可能感兴趣的:(Java学习,java,python,开发语言)