首页/文章列表/文章详情

反射快速入门

编程知识1942024-07-18评论

反射就是通过字节码文件获取类的成员变量、构造方法和成员方法的所有信息。
利用反射,我们可以获取成员变量的修饰符、名字、类型、取值。我们可以获取构造方法的名字、形参,并利用通过反射获取的构造方法创建对象。我们可以获取成员方法的修饰符、名字、形参、返回值、抛出的异常、注解,并运行通过反射获取的方法。

比如idea中的自动提示就是通过反射获取的,idea通过反射获取该对象的所有能调用的方法,并将它显示出来,又比如idea中函数的形参提示也是通过反射获取的。

反射是通过字节码文件对象获取成员变量、成员方法、构造方法的所有信息,所以,我们先要获取字节码文件对象,再去从字节码文件对象中获取成员变量、构造方法和成员方法,最后再进行解剖获取所有信息。

获取class对象的3种方式:

(1)class.forName("全类名");(2)类名.class;(3)对象.getClass();

那我们应该如何选择呢?

创建一个类的对象,我们需要经历以下3个阶段:

  • 源代码阶段:Java->class,在这个阶段,虚拟机是没有把代码加载到内存当中的,全都是硬盘中进行操作。在这个阶段用第一种方式获取class字节码文件对象。第一种方式最为常用。
  • 加载阶段:把字节码文件加载到内存中。这个阶段使用第二种方式来获取字节码文件对象。第二种方式通常都是当作参数进行传递。
  • 运行阶段:在该阶段使用第三种方式。当我们已经有了这个类的对象时才可以使用第三种方式。

利用反射获取构造方法:

Constructor<?>[] getConstructors()//返回所有公共构造方法对象的数组Constructor<?>[] getDeclaredConstructors()//返回所有构造方法对象的数组Constructor<T> getConstructor(Class<?>..parameterTypes)//返回单个公共构造方法对象Constructor<T> getDeclaredConstructor(Class<?>.. parameterTypes)//返回单个构造方法对象T newInstance(Object... initargs)//根据指定的构造方法创建对象setAccessible(boolean flag)//设置为true可以绕过访问控制权限,使得 private 属性或方法也可以被访问。//setAccessible(boolean flag)使用示例public class Example { private String privateField ="privateValue";}public class AnotherClass { public static void main(String[] args) throws Exception { Example instance = new Example(); Field field = Example.class.getDeclaredField("privateField"); field.setAccessible(true); System.out.println("Private Field Value:" + field.get(instance)); // 可以通过反射访问私有字段 }}

Class类中用于获取成员变量的方法:

Field[] getFields()//返回所有公共成员变量对象的数组Field[] getDeclaredFields()//返回所有成员变量对象的数组Field getField(String name)//返回单个公共成员变量对象Field getDeclaredField(Stringname)//返回单个成员变量对象void set(Object obj, Object value)//给成员变量赋值Object get(Object obj)//获取成员变量的值。setAccessible(boolean flag)//使用 setAccessible(true) 可以绕过访问控制权限,使得 private 属性或方法也可以被访问。//set,get示例public class Example { private String name; private int age; public static void main(String[] args) throws Exception { Example example = new Example(); Field nameField = Example.class.getDeclaredField("name"); Field ageField = Example.class.getDeclaredField("age"); // 设置字段值 nameField.set(example,"John Doe"); ageField.set(example, 30); // 获取字段值 System.out.println("Name:" + nameField.get(example)); System.out.println("Age:" + ageField.get(example)); }}

Class类中用于获取成员方法的方法:

Method[] getMethods()//返回类中所有公共成员方法对象的数组,包括继承的Method[] getDeclaredMethods()//返回类中所有成员方法对象的数组,不包括继承的Method getMethod(String name, Class<?>... parameterTypes)//返回单个公共成员方法对象Method getDeclaredMethod(String name, Class<?>... parameterTypes)//返回单个成员方法对象Object invoke(Object obj,Object... args)//运行方法//参数一:用obj对象调用该方法//参数二:调用方法的传递的参数(如果没有就不写)//返回值:方法的返回值(如果没有就不写)setAccessible(boolean flag)//使用 setAccessible(true) 可以绕过访问控制权限,使得 private 属性或方法也可以被访问。//invoke使用示例:public class Example { public void greet(String name) { System.out.println("Hello," + name +"!"); } public static void main(String[] args) throws Exception { Example example = new Example(); Method method = Example.class.getMethod("greet", String.class); // 调用 greet 方法 method.invoke(example,"John"); }}

注意:获取公共方法时也会获取父类中的所有公共方法。获取所有权限的方法时,就不会获取父类的方法

神弓

博客园

这个人很懒...

用户评论 (0)

发表评论

captcha