反射

反射的概念和作用

反射的概念:万事万物皆对象,类也是对象。通过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   表示实例的初始化参数
操作构造器对象
复制代码
 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 }
复制代码

 

 
 
 
 
  
posted @   溯鸣  阅读(149)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示