Java基础(七)

框架是个好东西,可早晚有一天会过时,这世界上就没有亘古不变的东西,来学下Java基础吧

反射机制

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

如何获取这些信息呢?依赖于Class对象,Class对象将一个类的方法,变量等信息告诉运行的程序

获取Class对象的两种方法:

已知类名为TargetObject

- Class alunbarClass = TargetObject.class;
- Class alunbarClass1 = Class.forName("cn.luckycurve.TargetObject");

反射使用实例

供调用的TargetObject类

public class TargetObject {
    private String value;

    public TargetObject() {
        value = "LuckyCurve";
    }

    public void publicMethod(String name) {
        System.out.println("I love " + name);
    }

    private void privateMethod(String name) {
        System.out.println("I hate " + name);
    }

}

调用Target的Main类

public class Main {
    //    操作Traget类
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class<?> targetClass = Class.forName("cn.luckycurve.demo9.TargetObject");

//        从Java 9 开始不推荐使用以下写法
//        TargetObject o = (TargetObject) targetClass.newInstance();
//        推荐写法为
        TargetObject target = (TargetObject) targetClass.getDeclaredConstructor().newInstance();

//        获取类中的所有方法
        Method[] methods = targetClass.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println("method name :" + method.getName());
        }

//        获取指定方法并调用,要指定方法名和参数信息
        Method publicMethod = targetClass.getDeclaredMethod("publicMethod", String.class);
//        由于是非静态方法,要指定调用方法的对象
        publicMethod.invoke(target, "Java");

//        直接获取和修改private类型的字段
        Field value = targetClass.getDeclaredField("value");
//        因为value是private的,取消安全检查,不然会抛出异常
        value.setAccessible(true);
        String string = (String) value.get(target);
        System.out.println("修改前 value:" + string);
        value.set(target,"LuckyCurve2");
        String string2 = (String) value.get(target);
        System.out.println("修改后 value:" + string2);

//        调用私有方法
        Method privateMethod = targetClass.getDeclaredMethod("privateMethod", String.class);
//        取消安全检查
        privateMethod.setAccessible(true);
        privateMethod.invoke(target,"lazy");
    }
}

<<<method name :publicMethod
<<<method name :privateMethod
<<<I love Java
<<<修改前 value:LuckyCurve
<<<修改后 value:LuckyCurve2
<<<I hate lazy

总结:

​ 1.调用非静态方法,要将对象传进invoke方法中

​ 2.所有声明为private的字段和方法,在使用前都要调用feild.setAccessible(true)或者method.setAccessible(true)来解除安全检查

静态编译和动态编译

  • 静态编译:在编译时确定类型,绑定对象
  • 动态编译:在运行时确定类型,绑定对象

C++里面有详细的描述(C++的语言颗粒度细,程序很容易涉及到底层)

反射的优缺点

  • 优点:动态编译,增加了灵活性
  • 缺点:运行效率低,需要JVM进行一系列解释操作。安全问题,反射甚至可以操作私有字段和方法(也是优点,增加了灵活性 )

反射的应用场景

反射是框架的灵魂

虽然开发的时候很难用到反射机制,但也不能说明反射机制没有什么用,动态代理的设计模式,模块化的开发,还有我们日常使用的Spring / Hibernate等框架,都大量用到了反射机制

  • JDBC连接数据库时候使用了Class.forName
  • Spring框架的IOC以及AOP
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值