Day26 反射

本文深入探讨了Java反射机制,包括如何通过反射获取构造方法、成员变量及其值,以及成员方法的调用。示例代码展示了如何获取`Class`对象,访问公共和私有成员,以及调用公共和私有方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 1,通过Class类对象获取当前类的构造方法

 Constructor 构造方法类


public class GetClassConstructor {
public static void main(String[] args) throws 
ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
/*
【加载】指定类的字节码文件,获取对应的Class对象
1. 让JVM根据类名,加载Person.java对应的字节码文件Person.class 到内存的代码区
2. 把加载到内存代码区Person.class 字节码文件生成一个Class类对象返回
*/
Class cls = Class.forName("com.qfedu.a_reflect.Person");
//Constructor 这是构造方法的类
//可以通过Class获取所有的【非私有化构造方法】,方法是Constructor[] getConstuctors();
Constructor[] constructors = cls.getConstructors();

for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("----------------------------------------------------");
//暴力反射
Constructor[] allConstructors = cls.getDeclaredConstructors();
for (Constructor constructor : allConstructors) {
System.out.println(constructor);
}

/*
根据参数获取具体的构造方法 
getConstructor(Class... parameterTypes);
不定参数列表,表示参数的类型要求是Class类型,但是数量不限制
在确定数据类型的情况下,可以直接通过数据类型.class获取对应Class数据类型
例如:
int.class String.class
*/
System.out.println("----------------------------------------------------");
Constructor aConstructor = cls.getConstructor(int.class, String.class);
System.out.println(aConstructor);

/*
构造方法Constructor对象获取完毕,怎么利用Constructor对象创建一个Person类对象
newInstance(Object... initargs) 
也是一个不定参的方法,需要的参数都是Object类型的,参数个数不确定
*/
Person p = (Person) aConstructor.newInstance(1, "海洋");
System.out.println(p.getId() + ":" + p.getName());
p.sleep(5);
p.game();
p.eat(); //任何通过反射机制,调用static修饰的成员方法,并且不报警告

/*
通过暴力反射,借助于指定的参数,获取private修饰的无参构造方法 
*/
System.out.println("----------------------------------------------------");
Constructor privateConstructor = cls.getDeclaredConstructor(null);
System.out.println(privateConstructor);

//setAccessible(boolean ) 给予操作Private修饰方法的权限
privateConstructor.setAccessible(true);
Person p2 = (Person) privateConstructor.newInstance(null);
p2.setId(2);
p2.setName("刘德华");

System.out.println(p2);

 2, 通过反射获取Class类对象里面所有的成员变量
 Field 成员变量类


public class GetClassField {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
//加载字节码文件,获取Class类对象
Class cls = Class.forName("com.qfedu.a_reflect.Person");

//获取所有用public修饰的成员变量
Field[] allPublicFields = cls.getFields();


for (Field field : allPublicFields) {
System.out.println(field);
}
System.out.println("$$");
//暴力反射
Field[] allFields = cls.getDeclaredFields();
for (Field field : allFields) {
System.out.println(field);
}
System.out.println("$$");
Field aPublicField = cls.getField("test");
System.out.println(aPublicField);
//set方法
//set(Oject obj, Object value);
//第一个参数: 要操作的是哪一个对象里面的成员变量
//第二个参数: 需要设置的值
Person p = (Person) cls.getConstructor(int.class, String.class).
newInstance(1, "狗蛋");
aPublicField.set(p, 20);

System.out.println(p.test);
System.out.println("$$");

Field aStaticField = cls.getField("testStatic");
System.out.println(aStaticField);
aStaticField.set(null, 20);
System.out.println(Person.testStatic);

System.out.println("$$");
Field aPrivateField = cls.getDeclaredField("id");
System.out.println(aPrivateField);
aPrivateField.setAccessible(true);
aPrivateField.set(p, 10);
System.out.println(p.getId());
}
}

3, 通过反射借助于Class类对象,获取这个类里面所有的成员方法
Method 就是成员方法类


public class GetClassMethod {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
//加载对应类的字节码文件,获取该类的Class类对象
Class cls = Class.forName("com.qfedu.a_reflect.Person");

//getConstructors() 
//获取所有的公共的方法,这里也会获取一些额外的方法???哪来的???
Method[] allPublicMethods = cls.getMethods();
for (Method method : allPublicMethods) {
System.out.println(method);
}
System.out.println("$$$");
//暴力反射
//能够获取Person里面的private方法, 并且能够过滤掉从父类继承而来的方法
Method[] allMethods = cls.getDeclaredMethods();
for (Method method : allMethods) {
System.out.println(method);
}

/*
通过反射机制,执行类中的成员方法 
invoke(Object obj, Object... args);
Object obj 这是底层调用该方法的类对象
the object the underlying method is invoked from
Object... args 不定参数,是执行该放的参数列表,是Object类型
args is arguments used for method call
*/
//向利用反射,创建一个当前类的对那个
System.out.println("$$$");
Person p = (Person) cls.getConstructor(int.class, String.class).
newInstance(1, "狗蛋");

//获取一个指定的方法,需要的参数是方法的名字字符串和参数列表,
Method aPublicMethod = cls.getMethod("sleep", int.class);
System.out.println(aPublicMethod);

aPublicMethod.invoke(p, 15);
System.out.println("$$");

//获取一个静态方法
Method aPublicStaticMethod = cls.getMethod("eat", null);
aPublicStaticMethod.invoke(null, null);

//利用暴力反射获取一个私有化的成员方法
Method aPrivateMethod = cls.getDeclaredMethod("testPrivate", null);
aPrivateMethod.setAccessible(true);
aPrivateMethod.invoke(p, null);
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值