<small id='hs6RyI'></small> <noframes id='2mEQ'>

  • <tfoot id='zSQjaU46'></tfoot>

      <legend id='HLPBrZ'><style id='qsWuZ'><dir id='4hNI'><q id='QVwuNXZt4'></q></dir></style></legend>
      <i id='KavNj'><tr id='meEWf0tHO'><dt id='mxJTYQAn'><q id='uMGgw0'><span id='uksGMv4i'><b id='5HSzp'><form id='aJmK4vsz'><ins id='E2wIyCf'></ins><ul id='Pb7m'></ul><sub id='6hOVCiHYTR'></sub></form><legend id='AIue'></legend><bdo id='9CRiItx'><pre id='eDvUZCwR8j'><center id='HEis'></center></pre></bdo></b><th id='uaSLpP7'></th></span></q></dt></tr></i><div id='MAaUt'><tfoot id='4ERYkeo0HC'></tfoot><dl id='4VBU'><fieldset id='GuajYZ'></fieldset></dl></div>

          <bdo id='q7xrgLU'></bdo><ul id='xc2tNp'></ul>

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

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

            admin 2019-05-16 257人围观 ,发现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