3C科技 娛樂遊戲 美食旅遊 時尚美妝 親子育兒 生活休閒 金融理財 健康運動 寰宇綜合

Zi 字媒體

2017-07-25T20:27:27+00:00
加入好友
Class對象虛擬機在class文件的載入階段,把類信息保存在方法區數據結構中,並在Java堆中生成一個Class對象,作為類信息的入口。聲明兩個類,Cat.java 和 Dog.javaclass 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對象一般有三種方式:通過實例變數方式public class test { public static void main(String args) { Dog dog = new Dog; Class clazz = dog.getClass; }}public class test { public static void main(String args) { Dog dog = new Dog; Class clazz = dog.getClass; }}通過類名方式public class test { public static void main(String args) { Class clazz = Dog.class; }}public class test { public static void main(String args) { Class clazz = Dog.class; }}通過這種方式時,只會載入Dog類,並不會觸發其類構造器的初始化。通過Class.forName(String classname)方式public class ClassTest { public static void main(String args) { try { Class clazz = Class.forName("zzzzzz.Dog"); } catch (ClassNotFoundException e) {} }}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<?> forName0(String name, boolean initialize, ClassLoader loader, Class> caller)1private static native Class<?> forName0(String name, boolean initialize, ClassLoader loader, Class> caller)其中initialize參數,用來告訴虛擬機是否需要對載入的類進行初始化,如果initialize為false,則不會進行初始化Dog類。Class clazz = Class.forName("zzzzzz.Dog", false, Dog.class.getClassLoader);1Class 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);}1 Class class_dog = Dog.class;2 Field fields = class_dog.getDeclaredFields;3 for (Field field : fields) {4 System.out.println(field.getName);5 }2、獲取類方法Class class_dog = Dog.class;Method methods = class_dog.getDeclaredMethods;for (Method method : methods) { System.out.println(method);}Class class_dog = Dog.class;Method methods = class_dog.getDeclaredMethods;for (Method method : methods) { System.out.println(method);}通過method.invoke(obj, ...args)可以調用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; }}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會拋出NoSuchMethodException異常。4、通過newInstance方法生成類實例Class class_dog = Dog.class;Dog dog = class_dog.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");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);Field f = Unsafe.class.getDeclaredField("theUnsafe");f.setAccessible(true);return (Unsafe)f.get(null);這種方式在使用Unsafe類進行黑魔法時經常用到。反射的性能問題Stackoverflow上,很多人覺得使用反射reflect會影響系統性能,主要有以下幾點看法:1、代碼的驗證防禦邏輯過於複雜,本來這塊驗證時在鏈接階段實現的,使用反射reflect時需要在運行時進行;2、產生過多的臨時對象,影響GC的消耗;3、由於缺少上下文,導致不能進行更多的優化,如JIT;不過現代JVM已經運行的足夠快,我們應該把主要重心放在複雜的代碼邏輯上,而不是一開始就進行各種性能優化。小編團隊開發群,你想要的都在這裡哦!學習,交流,源碼,開發工具 616 959 444應有盡有!小編先在這裡代表團隊謝過各位,歡迎學習Java各個階段的小夥伴們加入我們!

本文由yidianzixun提供 原文連結

寫了 5860316篇文章,獲得 23313次喜歡
精彩推薦