news 2026/6/16 1:09:02

Java_反射暴破创建对象与访问类中的成员

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java_反射暴破创建对象与访问类中的成员

通过反射创建对象:

1.方式一:调用类中的public修饰的无参构造器

2.方式二:调用类中的指定构造器

3.Class类相关方法:

newInstance:调用类中的无参构造器,获取对应类的对象

getConstructor(Class ....class):根据参数列表,获取对应的public构造器对象

getDecalaredConstructor(Class ....class):根据参数列表,获取对应的所有构造器对象

4.Constructor类相关方法:

setAccessible:爆破

newInstance(Object ...obj):调用构造器

案例演示:

测试1:通过反射创建某类的对象,要求该类中必须有public的无参构造

测试2:通过调用某个特定构造器的方式,实现创建某类的对象

package com.reflection.ReflactionCreateInstance; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class ReflectionCreateInstance { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { //先获取到User类的Class对象 Class<?> userClass = Class.forName("com.reflection.ReflactionCreateInstance.User"); //通过public的无参构造器创建实例 Object o = userClass.newInstance(); //通过public的有参构造器创建实例 //先得到对应的构造器,再去创建实例,并传入实参 /* constructor对象就是 public User(String name) { //有参public this.name = name; } String.class 是获取 String 类的 Class 对象,用于在反射中标识参数类型 */ Constructor<?> constructor = userClass.getConstructor(String.class); Object o1 = constructor.newInstance("大黄");//通过newInstance为形参赋值 //通过非public的有参构造器创建实例 Constructor<?> declaredConstructor = userClass.getDeclaredConstructor(int.class, String.class); //暴破 declaredConstructor.setAccessible(true);//暴破(暴力破解)使用反射,可以访问非公有的(private等)修饰的构造器 Object o2 = declaredConstructor.newInstance(5, "小黄"); System.out.println(o2); } } class User{ private int age = 10; private String name = "泥嚎"; public User() { //无参public } public User(String name) { //有参public this.name = name; } private User(int age, String name) { //有参private this.age = age; this.name = name; } @Override public String toString() { return "User{" + "age=" + age + ", name='" + name + '\'' + '}'; } }

通过反射访问类中的成员:

一.访问属性:

1.根据属性名获取field对象

Field f = clazz对象.getDeclaredField(属性名);

2.暴破:

f.setAccessible(true);//f是Field

3.访问

f.set(o,值);//o表示对象 System.out.println(f.get(o));

4.如果是静态属性,则set和get中的参数o,可以写成null

案例演示:

package com.reflection.ReflectionAccessProperty; import java.lang.reflect.Field; //演示反射访问(操作)属性 public class ReflectionAccessProperty_ { public static void main(String[] args) throws Exception{ //1.得到student类对应的class对象 Class<?> stuClass = Class.forName("com.reflection.ReflectionAccessProperty.Student"); //2.创建对象 Object o = stuClass.newInstance();//o的运行类型就是Student System.out.println(o.getClass());//Student //3.使用反射得到age 属性对象 Field age = stuClass.getField("age"); age.set(o,88);//通过反射来操作属性 System.out.println(o);//Student{age=88,name=null} System.out.println(age.get(o));//88,这样也可以 //4.使用反射操作name属性 //先得到name对应的field对象 Field name = stuClass.getDeclaredField("name");//name是私有的,不能使用getField() name.setAccessible(true); name.set(o,"张三"); name.set(null,"张三");//这样也可以,因为name是静态的,设置为null就等于给Student的所有实例都设置为"张三" System.out.println(name.get(o));//张三 System.out.println(name.get(null));//张三,只有静态属性才能置空 } } class Student{ public int age; private static String name; public Student() { } @Override public String toString() { return "Student{" + "age=" + age + ",name=" + name + '}'; } }

二.访问方法:

1.根据方法名和参数列表获取Method方法对象:

Method m = clazz.getDeclaredMethod(方法名,XX.class);//得到本类的所有方法

2.获取对象:

Object o = clazz.newInstance();

3.暴破:

m.setAccessible(true);

4.访问:

Object returnValue = m.invoke(o,实参列表);

5.如果是静态方法,则invoke的参数o,可以写成null

案例演示;

package com.reflection.ReflectionAccessMethod; import java.lang.reflect.Method; //演示通过反射调用方法 public class ReflectionAccessMethod { public static void main(String[] args) throws Exception{ //得到boss类对应的class对象 Class<?> bossClass = Class.forName("com.reflection.ReflectionAccessMethod.Boss"); //创建对象 Object o = bossClass.newInstance(); //调用public方法 //得到hi()对象 Method hi = bossClass.getMethod("hi", String.class); //调用 hi.invoke(o, "熊大"); //调用非public的静态方法 //得到say()对象 Method say = bossClass.getDeclaredMethod("say", int.class,String.class, char.class); say.setAccessible(true); System.out.println(say.invoke(o,5,"熊二",'a')); //因为say()是静态的,还可以将对象置空 System.out.println(say.invoke(null,5,"熊二",'a')); //返回值 //在反射中,如果方法有返回值,统一返回Object,但是它的运行类型和实际方法返回的类型是一样的 Object o1 = say.invoke(null, 300, "熊三", '男'); System.out.println(o1);//300 熊三 男 } } class Boss{ public int age; private static String name; public Boss() { //构造器 } private static String say(int n,String s,char c){ //静态方法 return n + " " + s + " " + c; } public void hi(String s){ //普通方法 System.out.println("hi" + s); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 19:26:35

【漏洞】Druid未授权访问漏洞及修复方案

漏洞描述&#xff1a;Druid(阿里巴巴数据库连接池)是一个开源的数据库连接池库,它提供了强大的数据库连接池管理和监控功能。核心原因&#xff1a;Druid 管理后台&#xff08;默认路径 /druid/index.html 或 /api/admin/druid/index.html&#xff09;默认未启用身份认证&#x…

作者头像 李华
网站建设 2026/6/15 22:34:34

17、Taylor UUCP 配置与使用指南

Taylor UUCP 配置与使用指南 1. UUCP 概述 UUCP(Unix-to-Unix Copy)是 20 世纪 70 年代末由 AT&T 贝尔实验室的 Mike Lesk 设计的,用于通过公共电话线建立简单的拨号网络。尽管如今拨号 PPP 和 SLIP 连接到互联网很流行,但许多希望在家庭计算机上收发电子邮件和 Usen…

作者头像 李华
网站建设 2026/6/15 17:54:17

22、NNTP与nntpd守护进程详解

NNTP与nntpd守护进程详解 1. NNTP简介 网络新闻传输协议(NNTP)为新闻交换提供了一种与C News及其他无原生NNTP支持的新闻服务器截然不同的方法。它不依赖于像UUCP这样的批处理技术在机器间传输新闻文章,而是允许通过交互式网络连接交换文章。NNTP并非特定软件包,而是RFC -…

作者头像 李华
网站建设 2026/6/10 12:30:19

【即插即用模块】SCI1区 | CNN为什么不能捕获长距离特征?双坐标注意力牛在哪:平均+最大池化并行,涨点必备,SCI保二区争一区!彻底疯狂!!!

0 论文信息 论文标题: Flora-NET: Integrating dual coordinate attention with adaptive kernel based convolution network for medicinal flower identification中文标题&#xff1a;Flora-NET&#xff1a;融合双坐标注意力与自适应核卷积网络的药用花卉识别论文链接论文代…

作者头像 李华
网站建设 2026/6/13 19:07:36

[GKCTF 2020]CheckIN

class ClassName {public $code null;public $decode null;function __construct() {// 1. 从 $_REQUEST&#xff08;GET/POST/Cookie&#xff09;中获取「Ginkgo」参数的值$this->code $this->x()[Ginkgo];// 2. 对 Ginkgo 的值做 base64 解码$this->decode base…

作者头像 李华