反射机制

通常,在开发过程中,为了提高程序的拓展性,通常会定义用于拓展的接口,每次扩展功能都需要修改代码传递一个新创建的对象,能不能不修改代码就完成这个动作?
不用new来完成,而是只获取class文件,在内部完成创建对象的动作。

反射机制概念

JAVA反射机制就是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法。对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能成为java语言的反射机制。
动态获取类中信息,就是java反射。可以理解为对类的解剖。要想对字节码文件进行解剖,必须要有字节码文件对象。
这就用到了Class类。

反射机制的应用

反射机制的两个关键的组成:一是要有用于拓展的接口,二是要有配置文件,用于记录拓展功能的类名。
创建实现了拓展功能的接口,在配置文件中设置其参数,在应用程序中添加读取配置文件的函数,即可实现实时的功能拓展,而不必修改程序的代码。

Class类的使用

1,获取字节码文件

获取字节码文件使用Class类的forName()方法

String className = "reflect.Person";
Class clazz = Class.forName(className);
2,创建类的对象

获取了字节码文件后,就可以创建类的对象
Class类的newInstance()方法可以调用该类的空参数构造函数

Person p = (Person)clazz.newInstance();

当要获取指定名称对应类所体现的对象时,若该对象初始化不使用空参数构造方法该怎么办呢?
既然是通过指定的构造函数进行对象的初始化,那么应该先获取该构造方法,通过字节码文件对象即可完成,该方法是:getConstructor(paramterTyps)

//获取到了指定的构造函数对象
Constructor constructor = clazz.getConstructor(String.class,int.class);
//通过该构造器对象的newInstance方法进行对象的初始化
constructor.newInstance("小强",30);
3,获取类的属性

使用getField(String name)和getDeclaredField(String name)方法可以获取类的属性对象(Field)
注意,若要使用该类实例的属性,需要先明确该属性所属对象,即必须先创建对象,并在设置属性时传入该对象

Class clazz = Class.forName("reflect.Person");
        //Field field = clazz.getField("age");//只能获取公有的,可以获取父类的
        Field field = clazz.getDeclaredField("age");//只获取本类,但包含私有
        //对私有字段的访问取消权限检查。暴力访问
        field.setAccessible(true);
        Object obj = clazz.newInstance();
        field.set(obj, 89);
        Object o = field.get(obj);
        System.out.println(o);
4,获取类的方法

和获取属性相似,使用getMethod(String name,parameterTypes)和getDeclaredMethod(String name,parameterTypes)方法可以获取类的属性对象(Method)
获取指定Class中的所有公共方法

Class clazz = Class.forName("reflect.Person");
        //Method[] methods = clazz.getMethods();//获取本类公有方法
        Method[] methods = clazz.getDeclaredMethods();//只获取本类中所有方法,包含私有
        for(Method method:methods){
            System.out.println(method);
        }

获取一个无参数方法

Class clazz = Class.forName("reflect.Person");
        Method method = clazz.getMethod("show", null);//获取空参数一般方法
        Constructor constructor = clazz.getConstructor(String.class,int.class);
        Object obj = constructor.newInstance("小明",20);
        method.invoke(obj, null);

获取一个有参数方法

Class clazz = Class.forName("reflect.Person");
        Method method = clazz.getMethod("paramMethod", String.class,int.class);//获取空参数一般方法
        Object obj = clazz.newInstance();
        method.invoke(obj, "小强",22);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值