当前位置: 首页 > news >正文

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); } }
http://www.zskr.cn/news/117451.html

相关文章:

  • 2025年12月希腊移民,香港移民,澳洲移民中介测评指南,资质合规与服务透明优选 - 品牌鉴赏师
  • PaperReding:《LLaMA: Open and Efficient Foundation Language Models》
  • 2025年12月浦东新区口腔诊所推荐:全科室覆盖机构口碑之选盘点 - 品牌鉴赏师
  • 2025年12月球墨铸铁,QT400-18球墨铸铁,球墨铸铁棒料公司推荐:行业测评与选择指南 - 品牌鉴赏师
  • 《Java Web开发入门很简单》——学习笔记,新手入门,收藏这篇就够了
  • javascript: Converts HTML documents to DOCX in the browser
  • 基于UWB定位的安全帽人员定位系统:技术架构和核心功能详解
  • Gurobi 重磅回归GAMS与GAMSPy
  • 再次紧急修复,Flutter 针对 WebView 无法点击问题增加新的快速修复
  • 学生管理系统源码 Python+Django+Vue 前后分离 设计文档
  • 【即插即用模块】SCI1区 IF 15.5!| 空间注意力融合模块聚合结构细节,跨注意力融合模块捕捉全局语义,兼顾细粒度与上下文!SCI保二区争一区!彻底疯狂!!!
  • 16、Linux 中 IPX 与 NCP 文件系统的使用与配置
  • iOS 18.1 - iOS 26.x 抢先开启国行 Ai、分屏,Misaka26 工具来袭!!!!! - 指南
  • 【即插即用模块】SCI1区 | CNN为什么不能捕获长距离特征?双坐标注意力牛在哪:平均+最大池化并行,涨点必备,SCI保二区争一区!彻底疯狂!!!
  • langfuse 使用
  • 基于大数据的交通信号智能控制系统的设计与实现任务书
  • 17、Taylor UUCP 配置与使用指南
  • 18、Linux 电子邮件管理全解析
  • 收藏!程序员转型大模型:不是从零开始,而是降维升级
  • Git入门学习
  • NVIDIA正式推出Nemotron 3:用开放模型重塑AI多智能体时代
  • 为什么越来越多跨境卖家从平台转向独立站?
  • SC4D50120H-JSM 碳化硅肖特基二极管
  • 【强烈推荐】LangGraph核心概念解析:State管理+实战案例,一篇搞定大模型开发
  • 第11讲 蓝牙模块与建议数据包解析
  • 揭秘知识图谱与大模型的黄金组合,解决大模型幻觉问题的实战指南!
  • SpringBean生命周期,动态代理
  • 2*8的lcd显示屏自动居中
  • 几种不同的技师展示、推荐形式,每个客户一上来就能找到喜欢的技师,立刻下单!
  • 基于大数据的餐饮食材管理系统的设计与实现开题报告