反射快速入门

cnblogs 2024-07-19 08:09:00 阅读 83

反射就是通过字节码文件获取类的成员变量、构造方法和成员方法的所有信息。

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

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

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

获取class对象的3种方式:

<code>(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");

}

}

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


上一篇: unsigned详讲(干货满满)

下一篇: C语言指针笔记

本文标签

JAVA   


声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。