Java动态加载与反射机制

反射是什么

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

知道一个概念:动态加载类
动态加载:程序只有在运行时才会知道程序创建的对象。
静态加载:程序在编译的时候已经知道程序的运行结果,即创建的对象。

动态加载的好处是:当我们的程序在运行时,需要动态的加载一些类这些类可能之前用不到所以不用加载到jvm,而是在运行时根据需要才加载,这样的好处对于服务器 ,不言而喻了。
java的反射机制就是这样增加程序的灵活性,避免将程序写死到代码里。

利用反射机制获取类

获取类的三种方法

已知一个Student类:
—.通过对象名.getClass()获得
Student stu = new Student(); //创建一个类的对象
Class clazz = stu.getClass(); //获取class对象
二.通过类名.class获得
Class clazz = Student.class; //获取class对象
三.通过Class.forName(“全类名”)
Class clazz = Class.forName(“全类名”) //获取class对象.此字符串必须是真实路径(包名.类名)
注:程序在运行中一个类只有一个class对象产生;所有反射获取类的方法都是从Class开始;这个class对象其实是一个类的字节码信息。
第三种方法是最常用的,也最能体现反射的本质。这个全类名字符串可以传入也可写在配置文件中等多种方法

动态创建类的实例对象

利用 类名.newInstance(),调用的类必须有无参构造器,否则创建失败
Object obj = clazz.newInstance();
也可以是Constructor声明类的新实例对象。
在这里插入图片描述

利用反射读取方法

类中的方法有公有和私有。私有的方法需要获得读取权限。见下文。

利用反射获取构造器并使用

批量获取构造器

        public Constructor[] getConstructors():所有"公有的"构造方法
        public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)

获取单个特定的构造器

  •      public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
        如:Class[] p={String.class,int.class};      //具有两个参数的构造器
        Constructor cons1 = cls.getConstructor(p);  //获取特定参数类型的构造器(共有方法)
    
  •      public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
        如:Class[] p={int.class};
        Constructor cons = cls.getDeclaredConstructor(p);
    
    调用构造方法,需给有参的构造方法传参
    Object obj1 = cons1.newInstance(“小红”,22);
    Object obj = cons.newInstance(14);

利用反射获取成员方法并调用

批量获取构造器

        public Method[] getMethods(): 获取所有"公有方法";(包含了父类的方法也包含Object类)
        public Method[] getDeclaredMethods(): 获取所有的成员方法,包括私有的(不包括继承的)

获取单个特定的构造器

  •     public Method getMethod(String name,Class<?>... parameterTypes):   单个共有的成员方法
                    参数:
                        name : 方法名;
                       Class ... : 形参的Class类型对象
    
  •      public Method getDeclaredMethod(String name,Class<?>... parameterTypes): 单个公有、私有、保护的成员方法
                  参数:
                       name : 方法名;
                      Class ... : 形参的Class类型对象
          如:String name="three";		 //Student类中有一个three(String )的私有方法
          Class[] types={String.class};    //Class[]类型列表;A.class表示A的类型
          Method method = cls.getDeclaredMethod(name, types); //根据方法名和参数类型 获取特定私有方法
          method.setAccessible(true);         ##解除私有限定,否则运行出错
          System.out.println(method);
          //调用私有方法three()
          Object objs = cls.newInstance();  //创建实例,执行了构造方法
          method.invoke(objs,"小强");      //invoke()第一个参数是类的实例,第二个是方法参数
    

利用反射获取成员变量并调用

批量获取成员方法

        Field[] getFields(): 获取所有的"公有字段"
        Field[] getDeclaredFields(): 获取所有字段,包括:私有、受保护、默认、公有;

获取单个成员方法

        Field getField(String fieldName):获取所有的"公有字段"
        Field getDeclaredField(String fieldName):获取所有字段,包括:私有、受保护、默认、公有;
        
        如://获取类的私有字段age
	Field field = cls.getDeclaredField("age");
	field.setAccessible(true);
	System.out.println("Field found: " + field.toString());
	System.out.println("Field found: " + field.get(objs).toString());
	//修改字段的值
	field.set(objs, 25);
	System.out.println("Field found: " + field.toString());
	System.out.println("Field found: " + field.get(objs).toString());
	
	结果:Field found: private int demo.myReflect.age
          Field found: 20
          Field found: private int demo.myReflect.age
          Field found: 25

动态执行方法invoke()

  • Object obj =method.invoke(对象,方法参数1,方法参数2, …)
    — invoke()第一个参数是类的实例,第二个是方法参数
  • 在反射中利用invoke()可以调用私有方法
  • invoke有返回值,返回被调用方法执行的结果,对象后面的参数是执行方法时候传递的参数。
Java反射运行Bean配置文件,反射获取使用了注解的方法等等,有兴趣可查看Class类说明文档。

如果以上总结对你有帮助,请给我一个在看、点赞、关注+赞赏。转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值