news 2026/4/3 2:50:08

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/4/1 10:27:18

雷达水位监测系统:野外在线雷达雨量水位监测站

Q1&#xff1a;传统水位测量受泥沙、漂浮物影响大&#xff0c;这款雷达水位站真能避开这些问题&#xff1f;​A1&#xff1a;非接触测量 K 波段雷达技术&#xff0c;恶劣环境也精准&#xff01; 这是水库管理员最认可的核心优势&#xff01;传统接触式测量&#xff08;如浮球、…

作者头像 李华
网站建设 2026/4/1 17:09:32

2025年接口错误自动分析工具对比与测试平台选型指南

核心观点摘要 1. 2025年接口错误自动分析工具呈现智能化、平台化趋势&#xff0c;主流方案在异常定位精度、报告生成能力及易用性上差异显著。 2. 自动化测试平台选型需重点关注接口错误根因分析能力&#xff08;如区分数据库/网络问题&#xff09;、测试结果可视化及报告自…

作者头像 李华
网站建设 2026/3/29 10:09:12

AI - 用 FastAPI 暴露你的第一个 Google ADK Agent

AI - 用 FastAPI 暴露你的第一个 Google ADK Agent1. 起点&#xff1a;我们已经有了一个最简单的 Agent2. 目标架构&#xff1a;把 Agent 变成一个 HTTP 服务3. 新增一个 api.py&#xff1a;FastAPI 入口 & ADK 运行时3.1 安装 FastAPI Uvicorn python-dotenv&#xff08…

作者头像 李华
网站建设 2026/3/23 4:44:29

vs的运行库区别,静态连接mt和动态链接md运行库

在Visual Studio&#xff08;VS&#xff09;中&#xff0c;MT、MTd、MD、MDd是C/C编译器的运行时库链接选项&#xff0c;它们决定了程序如何链接C运行时库&#xff08;CRT&#xff09;&#xff0c;直接影响程序的部署方式、性能、调试体验及跨模块内存管理。以下是具体分析&…

作者头像 李华
网站建设 2026/4/2 0:13:00

死锁的4个场景

死锁的四个必要条件 互斥条件&#xff08;Mutual Exclusion&#xff09;&#xff1a; 资源一次只能由一个线程占用&#xff0c;其他线程必须等待该资源释放后才能访问。 例如&#xff0c;互斥锁&#xff08;std::mutex&#xff09;就是一种互斥资源&#xff0c;同一时间只能有一…

作者头像 李华
网站建设 2026/3/27 10:20:13

SC4D50120H-JSM 碳化硅肖特基二极管

在新能源、工业控制等领域飞速发展的今天&#xff0c;功率器件的性能直接决定了系统的效率、可靠性与小型化水平。传统硅基器件逐渐难以满足高频、高温、高压场景下的严苛需求&#xff0c;而碳化硅&#xff08;SiC&#xff09;作为第三代半导体材料的核心代表&#xff0c;正以其…

作者头像 李华