<small id='03ClDmOaEW'></small> <noframes id='2vxf'>

  • <tfoot id='4E1a'></tfoot>

      <legend id='yZm0s'><style id='URQuIHB'><dir id='hZQxq4NeB'><q id='DOhQI'></q></dir></style></legend>
      <i id='FHwj6xdu5'><tr id='IN31tn'><dt id='1k4mZKNj'><q id='AbLZ'><span id='eOu2x'><b id='ih0q8dbHS'><form id='p2BlwJTmy1'><ins id='IDP0Sa'></ins><ul id='3KWp7G'></ul><sub id='9YtRupdX'></sub></form><legend id='ABhqDriEv'></legend><bdo id='E0aIlBc'><pre id='4SVnqC8'><center id='tomZgFTpw'></center></pre></bdo></b><th id='1UGEeRF'></th></span></q></dt></tr></i><div id='NvXE'><tfoot id='OCrz'></tfoot><dl id='aBqdR'><fieldset id='LDMb'></fieldset></dl></div>

          <bdo id='37awb'></bdo><ul id='xgsVX6MBW9'></ul>

          1. <li id='Sd4aH'></li>
            登陆

            一号站平台app下载-十年程序员说说不一样的Java反射机制

            admin 2019-05-16 295人围观 ,发现0个评论

            Class目标

            虚拟机在class文件的加载阶段,把类信息保存在办法区数据结构中,并在Java堆中生成一个Class目标,作为类信息的进口。

            声明两个类,Cat.java 和 Dog.java

            class Cat {
            private String name;
            private int age;
            static {
            System.out.println("Cat is load");
            }
            }
            class Dog {
            private String name;
            private int age;
            static {
            System.out.println("Dog is load");
            }
            }

            获取Class目标一般有三种办法:

            1. 经过实例变量办法
            public class test {
            public static void main(String[] args) {
            Dog一号站平台app下载-十年程序员说说不一样的Java反射机制 dog = new Dog();
            Class clazz = dog.getClass();
            }
            }
            1. 经过类名办法
            public class test {
            public static void main(String[] args) {
            Class clazz = Dog.class;
            }
            }

            经过这种办法时,只会加载Dog类,并不会触发其类结构器的初始化。

            1. 经过Class.forName(String classname)办法
            public class ClassTest {
            public static void main(String[] args) {
            try {
            Class clazz = Class.forName("zzzzzz.Dog");
            } catch (ClassNotFoundException e) {}
            }
            }

            在JDK源码完成中,forName办法会调用Native办法forName0(),它在JVM中调用findClassFromClassLoader()加载Dog类,其原理和ClassLoader相同,将会触发Dog类的类结构器初始化,forName0办法声明如下:

            private static native Class

            其间initialize参数,用来通知虚拟机是否需求对加载的类进行初始化,假如initialize为false,则不会进行初始化Dog类。

            Class clazz = Class.forName("zzzzzz.Dog", false, Dog.class.getClassLoader());

            反射机制

            反射机制reflect能够在运转期间获取类的字段、办法、父类和接口等信息。

            1、获取类字段

            Class class_dog = Dog.class;
            Field[] fields = class_dog.getDeclaredFields();
            for (Field field : fields) {
            System.out.println(field.getName());
            }

            2、获取类办法

            Class class_dog = Dog.class;
            Method[] methods = class_dog.getDeclaredMethods();
            for (Method method : methods) {
            System.out.prin一号站平台app下载-十年程序员说说不一样的Java反射机制tln(method);
            }

            经过method.invoke(obj, ...args)能够调一号站平台app下载-十年程序员说说不一样的Java反射机制用obj实例的method办法。

            3、获取对应的实例结构器,并生成类实例

            public class ClassTest {
            public static void main(String[] args) throws NoSuchMethodException {
            Class class_dog = Dog.class;
            Constructor constructor = class_dog.getConstructor(String.class, int.class);
            constructor.newInstance("Tom", 10);
            }
            }
            class Dog {
            private String name;
            private int age;
            public Dog(String name, int age) {
            this.name = name;
            this.age = age;
            }
            }

            假如没有显现的声明默许结构器,class_dog.getConstructor()会抛出NoSuchMethodExcep一号站平台app下载-十年程序员说说不一样的Java反射机制tion反常。

            4、经过newInstance()办法生成类实例

            Class class_dog = Dog.class;
            Dog dog = class_dog.newInstance();

            5、设置私有变量

            Class class_dog = Dog.class;
            Field name = class_dog.getDeclaredField("name");
            name.setAccessible(true);
            Dog dog = (Dog) class_dog.newInstance();
            name.set(dog, "Tom");

            6、获取私有变量

            Field f = Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);
            return (Unsafe)f.get(null);

            这种办法在运用Unsafe类进行黑魔法时经常用到。

            反射的功能问题

            Stackoverflow上,很多人觉得运用反射reflect会影响体系功能,首要有以下几点观点:

            1、代码的验证防护逻辑过于杂乱,原本这块验证时在链接阶段完成的,运用反射reflect时需求在运转时进行;

            2、发生过多的暂时粤菜目标,影响GC的耗费;

            3、因为短少上下文,导致不能进行更多的优化,如JIT;

            不过现代JVM现已运转的足够快,咱们应该把首要重心放在杂乱的代码逻辑上,而不是一开始就进行各种功能优化。

            请关注微信公众号
            微信二维码
            不容错过
            Powered By Z-BlogPHP