java反射机制

反射理解

简单理解

按照传统写法,想要调用一个方法,就需要new一个对象,再通过对象去.这个方法。而反射则是先通过外部的配置文件,去获取到该类和方法名,再调用他的invoke()方法来执行该方法。如下代码

//不使用反射:
Cat cat = new Cat();
cat.hello();

//使用配置文件和反射
配置文件内容:
method=hello
classfullpath=com.sky.llx.Cat

//读取配置文件调用 , 最终只能读取到字符串类型,不能创建对象

        Properties properties = new Properties();

            properties.load(new FileInputStream("src/main/java/re.properties"));
            String classfullpath = properties.get("classfullpath").toString();
            String method = properties.get("method").toString();
            System.out.println(classfullpath + "===" + method);



        //使用反射机制来解决
        //通过类路径来加载这个类
        Class cla = Class.forName(classfullpath);
        //获得类加载的对象实例
        Object o = cla.newInstance();
        System.out.println(o.getClass());
        //可以直接强转、但是这样和直接new并没有区别
//        Cat cat2 = (Cat) o;
//        cat2.hello();
        //通过方法名来获取到当前类中对应的方法
        Method method1 = cla.getMethod(method);
        //执行该方法'
        System.out.println("===================");
        method1.invoke(o);

单纯从这方面来看,反射相对传统方法来说十分麻烦。
但是,如果想要更改调用的方法,反射的好处就体现出来了
假设上述代码为源码,如刚刚的调用的为hello方法,如果下次想调用hi 方法,传统的方法中是写死的,不是动态的,想要调用只能修改源码。而通过反射来操作的话,只需要修改配置文件,就可以成功换方法。因为源代码的使用的反射,是动态获取的。

许多的框架的原理也就是反射,通过外部的配置文件来在不修改源代码的情况下,符合设计模式ocp(开闭原则,不修改源代码,扩容功能)。

反射的缺点:对执行速度有影响,耗时较高。。。

Class类

Class cla = Class.forName(classfullpath);
//代码原理
//Class类也是类,因此也会去继承Object类
//Class类最后会根据类路径来调用类加载器来创建对象
//对于某个类的Class类对象,在内存中只有一份,因此类只加载一次。
//每个类的实例都会记得自己是由哪个Class实例生成
//可以通过调用Class来得到一个完整的类的结构
//Class对象也是放在堆中的
=====Class调用的方法======
		//获取 路径类 对应的 Class 对象
        System.out.println(Class.forName(classfullpath));
        //获取 运行类型
        System.out.println(Class.forName(classfullpath).getClass());
        // 获取包名
        System.out.println(Class.forName(classfullpath).getPackage());
        // 获取类名
        System.out.println(Class.forName(classfullpath).getName());
        // 创建 路径类 对应的 对象实例
        System.out.println(Class.forName(classfullpath).newInstance());
        // 获取属性  此时获取的属性不能是私有的否则会报错
        System.out.println(Class.forName(classfullpath).getField("属性名"));
        // 给对应的属性赋值
        Class.forName(classfullpath).getField("属性名").set("属性名","值");
        // 遍历获取所有的属性
        Field[] fields = Class.forName(classfullpath).getFields();
        Arrays.stream(fields).forEach(System.out::println);

传统的New一个对象属于静态加载,即只要代码中有new对象的代码,无论该对象代码是否执行,都会进行加载,如果没有该类就会报错。
反射创建对象则属于动态加载,只有当执行到改代码时才会加载,如果没有该类,并且未执行该代码,则不会报错,只有当执行该代码且没有对应的类时才会报错。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值