1

java学习--反射机制

 2 years ago
source link: https://shu1l.github.io/2020/11/25/java-xue-xi-fan-she-ji-zhi/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

​ 反射是Java中一种动态(运行时),通过反射可以在java动态运行时,对于任意一个类,对象可以通过反射获取到他的类,类可以通过反射拿到所有方法(包括私有),动态获取信息,以及动态调用对象的方法的功能称为java语言的反射机制。

反射的具体使用步骤

在调用Java反射机制,主要步骤包括:

  • 获取 目标类型的Class对象.
  • 通过 Class 对象分别获取Constructor类对象、Method类对象 & Field 类对象.
  • 通过 Constructor类对象、Method类对象 & Field类对象分别获取类的构造函数、方法&属性的具体信息,并进行后续操作.

反射获取类的class对象

要想使用反射,我们首先需要获得代操作的类所对应的Clas对象。

1.常用的获取Class对象有四种方法:

  • 使用Class类的静态方法
Class clz = Class.forName("java.lang.String");
  • 使用类的.class语法
Class clz = String.class;
  • 使用对象的getClass()方法
String str = new String("Hello");
Class clz = str.getClass();
  • Type语法
Class<?> classType = Boolean.TYPE; 
System.out.println(classType);

反射创建类对象

常用两种方法:

  • 通过 Class 对象的 newInstance() 方法,只能使用默认的无参数构造方法。
Class clz = pen.class;
Pen pen = (pen)clz.newInstance();
  • 通过 Constructor 对象的 newInstance() 方法,可以选择特定的构造方法。
Class clz = pen.class;
Constructor constructor = clz.getConstructor();
Pen pen = (Pen)constructor.newInstance();

反射获取并调用类的构造函数(Constructor)

1.获取所有公有构造函数
Constructor[] conArray = clazz.getConstructors();
for(Constructor c : conArray){
System.out.println(c);
2.获取所有的构造函数(包括:私有、受保护、默认、公有)
conArray = clazz.getDeclaredConstructors();
for(Constructor c : conArray){
System.out.println(c);
}
3.获取公有、无参的构造函数
Constructor con = clazz.getConstructor(null);
System.out.println("con = " + con);
Object obj = con.newInstance();

反射获取并调用类的成员方法(Method)

1.反射有参数方法
Class a = Class.forName("org.xiaopan.fanshe.Pen");
Pen pen =(Pen) a.newInstance();
public String[] b(String[] b)
Method m = a.getMethod("b",String[].class);//获取方法,需要指定要获取的方法名
String[] strs = (String[]) m.invoke(pen, new Object[]{new String[]{"str1","str2","str3"}}); //使用new Object[]{}形式传入
2.反射无参数方法
Class a = Class.forName("org.xiaopan.fanshe.Pen");
Pen pen =(Pen) a.newInstance();
public void a()
Method m = a.getMethod("a", null);
m.invoke(pen,null);
3.反射静态方法
Class a = Class.forName("org.fanshe.test.Pen");
public static void c()
Method m = a.getMethod("c");
m.invoke(null); //静态方法,直接调用,类对象传入null即可。

反射获取类的成员属性&赋值(Field)

1.反射公共属性

通过Class对象的etFields() 方法获取 Class 类的属性。只能获取公有属性。

Class clz = Pen.class;
Field[] fields = clz.getFields();
for (Field field : fields) {
System.out.println(field.getName());
}
2.反射私有属性

通过Class 对象的 getDeclaredFields() 方法则可以获取包括私有属性在内的所有属性。

Class clz = Pen.class;
Field[] fields = clz.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getName());
}

反射调用Runtime,getRuntime执行本地代码

// 获取Runtime类对象
Class runtimeClass1 = Class.forName("java.lang.Runtime");

// 获取构造方法
Constructor constructor = runtimeClass1.getDeclaredConstructor();
constructor.setAccessible(true);

// 创建Runtime类示例,等价于 Runtime rt = new Runtime();
Object runtimeInstance = constructor.newInstance();

// 获取Runtime的exec(String cmd)方法
Method runtimeMethod = runtimeClass1.getMethod("exec", String.class);

// 调用exec方法,等价于 rt.exec(cmd);
Process process = (Process) runtimeMethod.invoke(runtimeInstance, cmd);

// 获取命令执行结果
InputStream in = process.getInputStream();

// 输出命令执行结果
System.out.println(IOUtils.toString(in, "UTF-8"));

​ Java反射机制是Java动态性中最为重要的体现,利用反射机制我们可以轻松的实现Java类的动态调用。Java的大部分框架都是采用了反射机制来实现的(如:Spring MVCORM框架等),Java反射在编写漏洞利用代码、代码审计、绕过RASP方法限制等中起到了至关重要的作用。

Java代码审计基础之反射 - FreeBuf网络安全行业门户

(4条消息) Java反射详解_潘建南的博客-CSDN博客

Java 反射由浅入深 | 进阶必备 (juejin.cn)

Java反射机制 · 攻击Java Web应用-[Java Web安全] (javasec.org)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK