java反射机制

一,反射的使用场景

1,java程序中许多对象在运行时会出现两种状态:编译时类型和运行时类型如:
Person p=new Student();
在执行时会执行子类的方法,即其中编译时类型为Person,运行时类型会变为Student
2,可以降低程序间的耦合度
3,java中的动态化

二,反射API

1,Class类:类
2,Field类:字段
3,Method类:方法
4,Constructor类:构造器

三,反射使用步骤

获取想要操作的类的Class对象(new出来的是实例对象,我们要获得Class对象)->使用反射api操作这些信息->使用反射调用方法

1,获取Class对象
1>通过调用某个对象的getClass()方法

 //获取类的实例对象
        Fruit fruit=new Fruit();
        //获取Class对象
        Class fruitClass=fruit.getClass();

2>调用某个类的class属性获取该类的Class对象

//2,通过类名获取
        Class clazz=Fruit.class;

3>使用Class类中的forName()静态方法(最安全,性能最好)

Class forName=Class.forName("com.reflection.Fruit");

2,使用反射api操作这些信息
1>获取构造函数API(四种)

//获取class对象
        Class clazz=Class.forName("com.reflection.Fruit");
        //1,根据指定参数获取public构造器
        Constructor constructor=clazz.getConstructor(String.class,double.class);
        System.out.println(constructor);
        //2,获取所有public构造器放入Constructor[]数组中
        Constructor[] constructors=clazz.getConstructors();
        //遍历数组
        for(Constructor constructor1:constructors){
            System.out.println(constructor1);
        }
        //3,根据指定参数获取public和非public构造器
        Constructor declaredConstructor=clazz.getDeclaredConstructor(String.class);
        System.out.println(declaredConstructor);
        //4,获取所有public和非public构造器放入Constructor[]数组中
        Constructor[] declaredConstructors=clazz.getDeclaredConstructors();
        //遍历数组
        for(Constructor declaredConstructor1:declaredConstructors){

2>获取类方法API(四种)

//获取类的class对象
        Class clazz = Class.forName("com.reflection.Fruit");
        //1,根据方法名和方法参数获取public方法,第一个参数为方法名,第二个为参数类型class对象
        Method method = clazz.getMethod("changeColor");
        System.out.println(method.toString());
        //2,获取所有public方法
        Method[] methods = clazz.getMethods();
        for (Method method1 : methods) {
            System.out.println(method1.toString());
        }
        //3,根据方法名和方法参数获取public和非public方法
        Method method2= clazz.getDeclaredMethod("changeType", String.class);
        System.out.println(method2.toString());
        //4,获取所有public和非public方法
        Method[] methods1= clazz.getDeclaredMethods();

3>获取Field字段变量(同上四种)
分别为:
getField(String name)//根据名称获取public变量
getFields()//获取所有public变量,返回Field[]数组
getDeclaredField(String name)//根据名称获取public和非public变量
getDeclaredFields()//获取所有public和非public变量
3,使用反射调用方法
1>method.invoke(“要调用的方法的名字所属的对象实体(就是方法所属对象实体)”,方法的参数值)
2>如何使用反射创建对象
★使用Class对象的newInstance()方法来创建该class对象对应的类实体,此方法要求该class对象对应的类有默认的空构造器
★先通过class对象获取指定的Constructor对象,再通过Constructor对象的newInstance()方法来创建class对象对用的类实体,可以选定任意构造器

//原始方法
        Fruit fruit=new Fruit();
        //反射方法1
        Class clazz=Class.forName("com.reflection.Fruit");
        Fruit fruit1=(Fruit) clazz.newInstance();
        fruit1.setName("西瓜");
        fruit1.setPrice(23.5);
        System.out.println(fruit1.toString());
        //反射方法2
        Constructor constructor=clazz.getConstructor(String.class,double.class);
        Fruit fruit2=(Fruit) constructor.newInstance("西瓜",23.5);
        System.out.println(fruit2.toString());

3>反射调用方法

 //反射调用方法
        Class clazz=Class.forName("com.reflection.Fruit");
        //获取方法对象
        Method method=clazz.getMethod("changeColor");
        //获取changeColor方法所在的实体对象
        Fruit fruit=(Fruit) clazz.newInstance();
        method.invoke(fruit);

四,反射优缺点

优点:
提高了java程序的灵活性和扩展性,降低了耦合性
缺点:
1,性能比普通方法低,一般用在扩展性和灵活性高的框架上,一般程序不建议使用
2,会破快java封装特性和代码结构,反射代码比一般代码更加复杂,不宜于维护

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值