Java之反射机制与优点

说到反射这个词,大部分开发者想到的也许是框架。可以说,反射是框架的灵魂,特别是在Spring的IOC技术中,接下来我来讲讲我对反射的理解

反射机制

Java之反射机制与优点_第1张图片
在讲反射之前,我们先来梳理java program的运行过程

  • 首先,需要先对java文件进行编译,转换成class文件(字节码文件),然后存储在磁盘中
  • 然后,在运行时,当遇到需要调用的class文件时,JVM会通过ClassLoader(类加载器)去磁盘转码class文件,而后存入内存中
  • 由上图可得:无论创建同类型的几个对象,内存中的该类型class对象仅仅只有一个,通过该class对象来获取其中的属性、方法,而后将获取到的属性、方法组成一个对象,反射与new一个对象都是如此做的
  • 而反射则是通过相应的class类型来获取内存中的class对象的所有信息

反射优点

经过上面的讲解,我们知道了java反射的机制,那么反射的好处是什么呢?

  • 优点:由于java是static type language(静态类型语言),对于所有代码的加载都是在编译时进行检验的,调用任何对象都必须先创建这个对象,那么在不同的代码中,会由于创建多个对象而造成代码冗余、性能下降,这样就不够灵活;但是利用反射即可解决这个问题,因为反射的作用时效是running time,只有在需要用到相关的program时,才会去加载相关的class对象,那么可提升代码的拓展性
  • 作用场景:
    • 对于不知类型的对象,如果想调用它的方法,那么可利用反射,绕过编译器的检测
    • 举例:
      • 场景一
        • Reflection(创建一个方法,传递的参数是不知道类型的)

           public class Reflection {
                public void refleMethod(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
                    Method method = object.getClass().getMethod("doSomething", null);
                    method.invoke(object, null);
                }
            }
          
        • RealObject(传递的对象)

            public class RealObject {
                public void doSomething() {
                    System.out.println("this is real object");
                }
            }
          
        • main

            public class Main {
                public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
                    Reflection reflection = new Reflection();
                    System.out.println("hello wolrd");
                    RealObject realObject = new RealObject();
                    reflection.refleMethod(realObject);
                }
            }
          
        • 运行结果

            hello wolrd
            this is real object
          
      • 总结:由上述例子可以看出反射的优点,在传递参数不知道类型的情况下,我们可以通过反射来获取其方法(如果存在的话),提高代码的拓展性,同时降低代码的耦合性
    • 场景二:
      • @annotation(注解的使用)
      • 由于java语言的约束,。在Spring的IoC的作用原理,则是对于上下文配置的对象,会统一的加载到spring的容器中。对于加了注解@Service的对象,则可以获取到Spring容器中的统一对象

总结

由于java的反射机制,我们可以提高代码的拓展性,同时降低了代码耦合性


(分割线)

反射的缺点
  • 通过Oracle公司提供的反射API,我看到了几点反射的缺点,特此记录,以待在以后开发的过程中验证
    • 原文如下在这里插入图片描述

    • 翻译:

      绩效开销
      由于反射涉及动态解析的类型,因此无法执行某些Java虚拟机优化。因此,反射操作的性能低于非反射操作,并且应避免在性能敏感应用程序中频繁调用的代码段中。

      安全限制
      Reflection需要运行时权限,在安全管理器下运行时可能不存在。对于必须在受限安全上下文中运行的代码,例如在Applet中,这是一个重要的考虑因素。

      内部接触
      由于反射允许代码执行在非反射代码中非法的操作,例如访问私有字段和方法,因此使用反射会导致意外的副作用,这可能导致代码功能失常并可能破坏可移植性。反射代码打破了抽象,因此可能会通过升级平台来改变行为。

若以上有何错误的地方,烦请指出,谢谢

参考资料:
What is reflection and why is it useful?:https://stackoverflow.com/questions/37628/what-is-reflection-and-why-is-it-useful
The Reflection API:https://docs.oracle.com/javase/tutorial/reflect/index.html

你可能感兴趣的:(Java之反射机制与优点)