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