news 2026/4/16 14:03: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/2 18:57:17

【JAVA】获取当前时间的上一周时间

背景&#xff1a;需要根据当前时间获取上一周时间&#xff0c;并查询这段时间的设备上报情况// 获取当前时间LocalDateTime nowTime LocalDateTime.now();// 获取当前时间前7天的时间点&#xff08;精确到秒&#xff09;LocalDateTime lastWeekTime nowTime.minus(7, ChronoU…

作者头像 李华
网站建设 2026/4/7 5:05:51

如何使用 WSL 在 Windows 上安装 Linux

如何使用 WSL 在 Windows 上安装 Linux 开发人员可以在 Windows 计算机上同时访问 Windows 和 Linux 的强大功能。 借助适用于 Linux 的 Windows 子系统&#xff08;WSL&#xff09;&#xff0c;开发人员可以安装 Linux 分发版&#xff08;如 Ubuntu、OpenSUSE、Kali、Debian、…

作者头像 李华
网站建设 2026/4/13 18:27:59

SAP CDS 带参数传输的视图

以下为CDS代码 AbapCatalog.sqlViewName: Z_VYYY_CDS_04AbapCatalog.compiler.compareFilter: trueAbapCatalog.preserveKey: trueAccessControl.authorizationCheck: #NOT_REQUIREDEndUserText.label: 加入传参Metadata.ignorePropagatedAnnotations: true// distinct …

作者头像 李华
网站建设 2026/4/14 23:47:36

致学弟学妹:一位过来人的C++编程心路与肺腑之言

致学弟学妹&#xff1a;一位过来人的C编程心路与肺腑之言 亲爱的学弟学妹们&#xff1a; 写下这些文字的时候&#xff0c;窗外是凌晨三点的灯光&#xff0c;屏幕上跳动着刚调试通过的代码。我想起八年前&#xff0c;自己像你们一样&#xff0c;坐在大学的机房里&#xff0c;面…

作者头像 李华