1.反射技术应用场景和特点
反射技术:动态的获取指定类以及动态的调用类中的内容。
应用场景:现在开发了一个my app的应用程序,想对其中的功能进行扩展,那么怎么能让后期出现的类被写好的应用程序所使用呢?通常的做法是实现相应的接口,实现完接口之后呢?我们需要在my app的源代码中使用接口创造相关对象。然而,app一般不会提供给你源代码,只是提供给你了.class文件,没法new 创建对象,这下怎么办呢?
2.字节码文件对应的类
3.获取字节码文件对象
package cn.itcast.reflect.demo; import cn.itcast.reflect.domain.Person; public class Reflect_GetClassDemo { public static void main(String[] args) { /* * 要想获取字节码文件中的成员,要先获取字节码文件对象。 获取字节码文件对象方式: * 1.通过object类中的getClass方法。 * 虽然通用,但是前提必须要指定类,并对该类进行对象的创建,才可以调用getClass方法。 * * 2.使用的是任意数据类型的静态成员class,所有数据类型都具备的一个属性。 * 好处:不用new对象,但是,还需要使用具体的类。 * * 3.使用class类中的forName方法,通过给定类名获取对应的字节码文件对象。 * 这种方式很爽,只要知道类的名字就可以了,获取对应的字节码文件由forName方法自动完成。 * 这就是反射技术使用的获取字节码文件对象的方式。 * */ getClass_1(); getClass_2(); getClass_3(); } private static void getClass_3() { // TODO Auto-generated method stub String calssName ="cn.itcast.reflect.domain.Person"; try { Class clazz = Class.forName(calssName); System.out.println(clazz.getName()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static void getClass_2() { // TODO Auto-generated method stub Class clazz = Person.class; System.out.println(clazz.getName()); // cn.itcast.reflect.domain.Person } private static void getClass_1() { // TODO Auto-generated method stub Person p1 = new Person(); Person p2 = new Person(); Class clazz1 = p1.getClass(); Class clazz2 = p2.getClass(); System.out.println(clazz1.getName()); // cn.itcast.reflect.domain.Person System.out.println(clazz1 == clazz2); // true } }
4.动态创建字节码对象所表示的类的对象
package cn.itcast.reflect.demo; import cn.itcast.reflect.domain.Person; public class Reflect_GetClassDemo { public static void main(String[] args) throws Exception { getClass_3(); } private static void getClass_3() throws ClassNotFoundException, InstantiationException, IllegalAccessException { // TODO Auto-generated method stub String calssName = "cn.itcast.reflect.domain.Person"; Class clazz = Class.forName(calssName); System.out.println(clazz.getName()); // 通过newInstance()就可以创建字节码文件所表示的类的实例。 Object obj = clazz.newInstance(); } }
5.常见的异常解析
package cn.itcast.reflect.demo; public class Reflect_GetClassDemo { public static void main(String[] args) throws Exception { getClass_3(); } private static void getClass_3() throws ClassNotFoundException, InstantiationException, IllegalAccessException { // TODO Auto-generated method stub String calssName = "cn.itcast.reflect.domain.Person"; Class clazz = Class.forName(calssName); // System.out.println(clazz.getName()); // 通过newInstance()就可以创建字节码文件所表示的类的实例。 // 通常被反射的类都提供空参数的构造函数,如果没有对应的构造函数,会报InstantiationException // 如果有提供,但是权限不够,会报IllegalAccessException Object obj = clazz.newInstance(); } }
6.通过给定的构造函数进行实例化
package cn.itcast.reflect.domain; public class Person { private String name; private int age; public Person() { // TODO Auto-generated constructor stub System.out.println("person run"); } public Person(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }
package cn.itcast.reflect.demo; import java.lang.reflect.Constructor; public class Reflect_GetConstructor { public static void main(String[] args) throws Exception { /* * 如果要通过指定的构造函数初始化对象怎么办呢? * 思路: * 1.获取字节码文件对象; * 2.在获取给定的构造函数; * 3.通过该构造函数初始化对象。 */ getConstructorDemo(); } public static void getConstructorDemo() throws Exception { // TODO Auto-generated method stub String className = "cn.itcast.reflect.domain.Person"; Class clazz = Class.forName(className); //获取指定的构造器,获取Person类中带参数的Sting,int构造函数 Constructor cons = clazz.getConstructor(String.class,int.class); //有了构造对象后,通过构造器对象来初始化该类对象 Object obj = cons.newInstance("lisi",21); System.out.println(obj); } }
7.获取字段与暴力访问
package cn.itcast.reflect.demo; import java.lang.reflect.Field; public class Reflect_GetField { public static void main(String[] args) throws Exception { /* * 获取字段 */ getFieldDemo(); } public static void getFieldDemo() throws Exception { // TODO Auto-generated method stub String className = "cn.itcast.reflect.domain.Person"; Class clazz = Class.forName(className); String fieldName = "age"; //获取字段 // Field field = clazz.getField(fieldName);//获取的是公有的字段 Field declaredField = clazz.getDeclaredField(fieldName); System.out.println(declaredField); //对其进行值的设置,必须先有对象 Object obj = clazz.newInstance(); // declaredField.set(obj, 30); //IllegalAccessException,age字段是私有的,不能直接修改 declaredField.setAccessible(true); declaredField.set(obj, 30); System.out.println(declaredField.get(obj));//获取字段的值 } }
package cn.itcast.reflect.domain; public class Person { public String name; private int age; public Person() { // TODO Auto-generated constructor stub System.out.println("person run"); } public Person(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }
8.获取方法
package cn.itcast.reflect.domain; public class Person { public String name; private int age; public Person() { // TODO Auto-generated constructor stub System.out.println("person run"); } public Person(String name, int age) { super(); this.name = name; this.age = age; } public void show(String name, int age) { System.out.println("show run... name =" + name + ",age=" + age); } public static void staticShow() { System.out.println("staticShow run..."); } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }
package cn.itcast.reflect.demo; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Reflect_GetMethodDemo { public static void main(String[] args) throws Exception { /* * 获取方法 */ getMethodDemo(); } public static void getMethodDemo() throws Exception { // TODO Auto-generated method stub String className = "cn.itcast.reflect.domain.Person"; Class clazz = Class.forName(className); Object obj = clazz.newInstance(); String methodName = "show"; Method method = clazz.getMethod(methodName, String.class, int.class); method.invoke(obj, "wangcai", 20); // show run... name =wangcai,age=20 // 获取静态方法 String methodName2 = "staticShow"; Method method2 = clazz.getMethod(methodName2, null); method2.invoke(null, null); // staticShow run... } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)