反射
反射的概念和作用
反射的概念:万事万物皆对象,类也是对象。通过Class文件对象,去使用该文件中的成员变量,构造方法,成员方法。Class类:成员变量 Field 构造方法Constructor 成员方法Method
引用:通过反射创建类对象和使用类对象。
反射的作用:创建对象。
传统方式:只能静态的创建java对象;前提是必须预先知道要使用的类。如果要修改使用的类,必须修改源码。但是,如果无法确定要执行的对象怎么办?(使用反射)
Person p=new Person();
反射创建类对象:实现了java对象的动态创建
缺点:反射的代码效率低,影响程序性能.
获取类对象
Class.forName("类的全限定路径"); 创建类对象使用较多类名.class 操作反射方法较多
对象名.getClass() 操作反射方法较多
注意:一个类只有一个类对象
1 //反射获取类对象 2 public static void getCla() throws ClassNotFoundException{ 3 //传统方式 4 Person p=new Person(); 5 //反射创建类对象 6 //第一种方式--->创建类对象 7 Class cla01=Class.forName("com.su.pojo.Person"); 8 //第二种方式---->调用底层使用反射封装的方法 9 Class cla02=Person.class; 10 //第三种方式---->调用底层使用反射封装的方法 11 Class cla03=new Person().getClass(); 12 13 System.out.println("获取类对象的包名---->"+cla01.getPackage()); 14 System.out.println("获取类的修饰符----->"+cla01.getModifiers()); 15 System.out.println("获取类的名称(全限定)----->"+cla01.getName()); 16 System.out.println("获取类的名称(类名)----->"+cla01.getSimpleName()); 17 System.out.println("获取类的父类的类对象----->"+cla01.getSuperclass()); 18 }
操作属性(成员变量)
获取类对象获取类属性
getFields() 获取所有的公共字段包括父类 返回Field[]
getDeclaredFields() 获取所有声明的字段(不包括父类) 返回Field[]
getField(String name) 获取指定的公共字段包括父类 返回Field
getDeclaredField(String name) 获取指定的声明的字段(不包括父类) 返回Field
操作类属性
操作静态属性
类属性对象.get(null) 返回静态属性的值
类属性对象.set(null,"值") 赋值
操作非静态属性
类属性对象.get(Object obj);
类属性对象.set(Object obj,"值");
1 public static void operField() throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException{ 2 //获取类对象 3 Class cla=Class.forName("com.su.pojo.Student"); 4 //获取反射类属性 5 //获取类及其父类的公共字段 6 Field[] fds = cla.getFields(); 7 for(Field f:fds){ 8 System.out.println("获取属性名------>"+f.getName()); 9 System.out.println("获取修饰符------>"+f.getModifiers()); 10 System.out.println("获取类型------>"+f.getType());//返回的是类型的Class对象 11 } 12 //获取类声明的所有字段 13 Field[] fds2=cla.getDeclaredFields(); 14 for(Field f:fds2){ 15 System.out.println("获取属性名----->"+f.getName()); 16 System.out.println("获取修饰符------>"+f.getModifiers()); 17 System.out.println("获取类型------>"+f.getType());//返回的是类型的Class对象 18 } 19 //获取指定的字段 20 Field f=cla.getField("pname");//指定获取类及其父类的公共字段 21 System.out.println(f.getName()); 22 Field f2=cla.getDeclaredField("money");//指定获取类的所有字段 23 System.out.println(f2.getName()); 24 Field f3=cla.getSuperclass().getDeclaredField("pname");//指定获取父类声明的字段 25 System.out.println(f3.getName()); 26 //操作字段值 27 //操作静态属性 28 Field fs=cla.getDeclaredField("money"); 29 fs.set(null,2000); 30 System.out.println(fs.get(null)); 31 //操作非静态属性 32 Field fd=cla.getDeclaredField("sname"); 33 Object obj=cla.newInstance(); 34 fd.set(obj, "李四"); 35 System.out.println(fd.get(obj)); 36 //暴力反射操作私有化属性(了解) 37 Field fd2=cla.getDeclaredField("ssex"); 38 fd2.setAccessible(true);//暴力反射,操作私有化属性,不安全 39 Object obj2=cla.newInstance();//获取实例化对象 40 System.out.println(fd2.get(obj2)); 41 42 }
暴力访问:fd2.setAccessible(true); 可操作私有化属性,忽略private修饰符,反射的对象在使用时取消了java语言访问检查。
操作方法
获取类对象获取方法对象
getMethods() 获取所有的公共方法包括父类
getDeclaredMethods() 获取所有声明的方法不包括父类
getMethod(String name,Class...cla) 获取指定的公共方法
String name 表示方法名
Class...cla 表示方法接收的参数类型的类对象
getDeclaredMethod(String name,Class...cla) 获取指定的声明方法
String name 表示方法名
Class...cla 表示方法接收的参数类型的类对象
操作方法
静态方法
方法对象.invoke(null,参数值1,参数值2,....);
方法对象.invoke(null,null);
非静态方法
Object obj=cla.newInstance();
方法对象.invoke(obj,参数值1,参数值2,....)
方法对象.invoke(obj,null)
1 //操作方法 2 private static void operMethod() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException { 3 //获取类对象 4 Class cla=Class.forName("com.su.pojo.Student"); 5 //获取类方法对象 6 //获取所有的公共方法包括父类 7 Method[] ms=cla.getMethods(); 8 for(Method m:ms){ 9 System.out.println("获取方法名--->"+m.getName()); 10 } 11 //获取所有声明的方法不包括父类 12 Method[] ms2=cla.getDeclaredMethods(); 13 for(Method m:ms2){ 14 System.out.println("获取方法名--->"+m.getName()); 15 } 16 //获取指定的公共方法包括父类 17 Method m=cla.getMethod("pHi", int.class,String.class); 18 System.out.println(m.getReturnType()); 19 //获取指定的声明的方法,不包括父类 20 Method m2=cla.getDeclaredMethod("sHello",null); 21 System.out.println(m2.getName()); 22 //执行方法 23 //静态方法 24 Method m3=cla.getDeclaredMethod("sHi",String.class); 25 m3.invoke(null, "静态方法"); 26 //非静态 27 Method m4=cla.getDeclaredMethod("sHi",int.class,String.class); 28 m4.invoke(cla.newInstance(), 3,"非静态方法"); 29 }
操作构造器
获取类对象获取构造器对象
getConstructors() 获取所有的公共构造方法包括父类
getDeclaredConstructors() 获取所有声明的构造方法不包括父类
getConstructor(Class...cla) 获取指定的构造方法
Class...cla 表示要获取的构造方法的参数个数及数据类型的类对象
newInstance(Object...initargs) 获取该构造方法的声明类的新实例,并用指定的初始化参数初始该实例
Object...initargs 表示实例的初始化参数
getDeclaredConstructors() 获取所有声明的构造方法不包括父类
getConstructor(Class...cla) 获取指定的构造方法
Class...cla 表示要获取的构造方法的参数个数及数据类型的类对象
newInstance(Object...initargs) 获取该构造方法的声明类的新实例,并用指定的初始化参数初始该实例
Object...initargs 表示实例的初始化参数
操作构造器对象
1 //反射操作构造器 2 private static void operConstructor() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { 3 //获取类对象 4 Class cla=Class.forName("com.su.pojo.Student"); 5 //获取构造器方法对象 6 Constructor[] cs=cla.getConstructors(); 7 for(Constructor c:cs){ 8 System.out.println(c.getName()); 9 } 10 //获取指定的构造器 11 Constructor c=cla.getConstructor(String.class); 12 //创建实例化对象 13 Object obj= c.newInstance("女"); 14 System.out.println(cla.getDeclaredMethod("getSsex",null).invoke(obj,null)); 15 16 Student s=new Student("女"); 17 System.out.println(s.getSsex()); 18 19 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通