反射机制之发生什么事了?

反射机制的使用

一句话描述反射机制的作用就是:在当前类或者其他类再运行状态中,可以动态的获取自身或者其他类的信息,包括属性,方法,修饰符,参数,参数类型等,并且能够进行直接修改一些属性和运行方法。

使用流程

1先获取目标类的Class,有三种方法

				//方法1根据全限定名称获取到类
          Class doMath =Class.forName("com.njupt.third.DoMath");
          //方法2通过类名的方式
          Class doMath =DoMath.class;
        //方法3先获取对象,再根据对象来获取
        DoMath doMath1= new DoMath();
        Class doMath = doMath1.getClass();

2对Class类进行实例化对象,两种方法

1.通过已经过期的方法直接获取
Object o = doMath.newInstance();

newInstance需要注意的是,该方法的底层是通过目标类的无参构造方法,如果 没有无参构造方法,会出异常!!!

2,通过使用构造方法
Constructor constructor = doMath.getConstructor();
        Object o = constructor.newInstance();

3获取类中的属性需要先获取到属性的修饰符,类型,名称等信息

				Field[] declaredFields = doMath.getDeclaredFields();
        for(Field field :declaredFields){
    
    
            System.out.print("属性名:"+field.getName() +" ");
            System.out.print("属性类型:"+field.getType()+" ");
            System.out.print("属性修饰符"+field.getModifiers());
            System.out.println();
        }
        

就会获取到如下结果

属性名:num 属性类型:double 属性修饰符2
属性名:name 属性类型:class java.lang.String 属性修饰符10
属性名:age 属性类型:int 属性修饰符1

注意修饰符是用2进制表示的,如果是1就是public 2就是private等

4获取到属性后可以修改属性的值

Field name = doMath.getDeclaredField("name");
        name.setAccessible(true);
        name.set(o,"小娜娜");
        System.out.println(name.getModifiers());

5获取类中的方法需要先获取到方法的修饰符,返回值,名称,参数等信息

Method[] declaredMethods = doMath.getDeclaredMethods();
for(Method method : declaredMethods){
    
    
            System.out.print("方法名:"+method.getName()+" ");
            System.out.print("方法修饰符:"+method.getModifiers()+" ");
            System.out.print("方法返回值类型:"+method.getReturnType());
            System.out.print("方法返回值类型:"+ Arrays.toString(method.getParameterTypes()));
            System.out.println();
        }
方法名:main 方法修饰符:9 方法返回值类型:void方法返回值类型:[class [Ljava.lang.String;]
方法名:add 方法修饰符:2 方法返回值类型:int方法返回值类型:[int, int]
方法名:print 方法修饰符:9 方法返回值类型:void方法返回值类型:[class java.lang.String]

注意getModifiers()的返回类型都是整数,但是它却代表着修饰符,

PUBLIC: 1
PRIVATE: 2
PROTECTED: 4
STATIC: 8
FINAL: 16
SYNCHRONIZED: 32
VOLATILE: 64
TRANSIENT: 128
NATIVE: 256
INTERFACE: 512
ABSTRACT: 1024
STRICT: 2048

6执行方法

1.实例方法的执行
先获取方法,和参数调用invoke方法,对于实例方法来说第一个参数是对象,后面的参数是方法的参数

Method add = doMath.getDeclaredMethod("add", int.class, int.class);
        add.setAccessible(true);
        add.invoke(o,3,4);

2静态方法的执行(直接调用类的main方法!)

Method main = doMath.getDeclaredMethod("main", String[].class);
        main.invoke(null,new String[]{
    
    null});

猜你喜欢

转载自blog.csdn.net/m0_56184347/article/details/123935633