java基礎-反射技術(磨礪營馬劍威java)

磨礪營馬劍威

在Java運行時環境中,對於任意一個類,可否知道這個類的哪些屬性和方法?對於任意一個對象,可否調用它的任意一個方法?答案是確定的。這種動態獲取類的信息以及動態調用對象的方法的功能來自於Java語言的反射(Reflection)機制。 反射給java提供了,運行時獲取一個類實例的可能,這一點很是靈活,你僅僅傳一個類的全限定名,就能經過反射,來獲取對應的類實例,咱們通常會用Class類,來調用這個被反射的Objcet類下的:構造方法,屬性,或方法等。 反射在一些開源框架裏用的很是之多,Spring,Struts,Hibnerate,MyBatics都有它的影子,反射雖然很靈活,可以使得寫的代碼,變的大幅精簡,因此在用的時候,必定要注意具體的應用場景。 反射的優缺點以下: 優勢: A:可以運行時動態獲取類的實例,大大提升系統的靈活性和擴展性。 B:與Java動態編譯相結合,能夠實現無比強大的功能 缺點: A:使用反射的性能較低 B:使用反射相對來講不安全 C:破壞了類的封裝性,能夠經過反射獲取這個類的私有方法和屬性 任何事物,都有兩面性,反射的優勢,也同是就是它的缺點,因此,沒有好與壞,只有最合適的場景,一陰一陽,纔是天道平衡的條件。 在反射API中咱們重點關注一下幾個類: Class -- 表明類 Field -- 表明屬性(成員變量) Method -- 表明方法 Constructor -- 表明構造方法 1、Class Java中不論一個類產生了多少個對象,這些對象的Class對象都始終是一個。Class對象中含有該類的任何信息(屬性,方法,類名,父類,包等),在Java中獲取Class對象的方法有三種: // 第一種方法:類名.class Class cla = Student.class; Class as =int.class; // 基本數據類型惟一能點出的就是class // 第二種方法:經過對象調用.getClass() Student stu =newStudent(); Class c = stu.getClass(); // 第三種方法:經過類的全限定名獲取 try{ Class c1 = Class.forName("entity.Student"); }catch(ClassNotFoundException e) { e.printStackTrace(); } System.out.println(cla.getName()); // 全限定名 System.out.println(Modifier.toString(cla.getModifiers())); System.out.println(cla.getSimpleName()); System.out.println(cla.getPackage().getName()); 能夠經過Class對象產生該類的對象,以下: // 獲取Class對象 Class cla = Student.class; /* 1. 直接建立對象(調用默認無參構造方法),類裏必需要有默認構造方法 / Object obj1 = cla.newInstance(); System.out.println(obj1); 2、Constructor 若是想經過有參構造方法來建立對象,那麼這時候就得先獲取有參構造方法,再經過有參構造方法來建立對象: // 獲取Class對象 Class cla = Student.class; / 1. 直接建立對象(調用默認無參構造方法),類裏必需要有默認構造方法 / Object obj1 = cla.newInstance(); System.out.println(obj1); / 2. 經過無參構造方法建立對象,和第一種方法效果同樣 / Constructor no = cla.getConstructor(); // 先獲取無參構造方法 Object obj2 = no.newInstance(); System.out.println(obj2); / 3. 經過有參構造方法建立對象 */ Constructor has = cla.getDeclaredConstructor(String.class,int.class); // 形參 Object obj3 = has.newInstance("老李", 23); // 傳入的是實參 System.out.println(obj3); 3、Field Field表明是類中的屬性,咱們能夠獲取屬性,並修改其值(注:先得有對象才能修改值,另:修改沒權限的屬性時,須要先打開該屬性的權限)。 // 獲取Class對象 Class cla =newStudent().getClass(); // 獲取構造方法 Constructor con = cla.getConstructor(String.class,int.class); // 建立對象 Object obj = con.newInstance("如來", 222); // 獲取要操做的屬性 Field name = cla.getDeclaredField("name"); // 反射操做private屬性的時候,須要打開權限 name.setAccessible(true); // 獲取obj的name屬性值 System.out.println(name.get(obj)); // 把obj的name屬性值改成:菩提 name.set(obj, "菩提"); System.out.println(name.get(obj)); // 把id設置爲10086 Field id = cla.getDeclaredField("id"); id.set(obj, 10086); System.out.println(id.get(obj)) 4、Method Method表明類中的方法,和Field操做類型: // 獲取Class對象 Class cla = Student.class; // 建立對象 Object obj = cla.getDeclaredConstructor(String.class,int.class).newInstance("達摩", 666); // 獲取要操做的方法 Method showNo = cla.getDeclaredMethod("show"); Method showHas = cla.getDeclaredMethod("show", String.class); Method calc = cla.getDeclaredMethod("calc",int.class,double.class); calc.setAccessible(true); // 調用方法 showNo.invoke(obj); showHas.invoke(obj, "老衲"); Object value = calc.invoke(obj, 10086, Math.PI); System.out.println(value); 咱們能夠用反射來改進簡單工廠模式: packagedemo08; importjava.io.FileInputStream; importjava.util.Properties; publicclassPetFactory { publicstaticvoidmain(String[] args) { System.out.println(getInstance("dog")); // demo08.Dog@67a9b034 } // 工廠方法 publicstaticPet getInstance(String tag) { Properties p =newProperties(); try{ p.load(newFileInputStream("conf/pet.properties")); }catch(Exception e) { System.out.println("加載配置文件錯誤!"); } String className = p.getProperty(tag); try{ // 利用反射建立對象 Class cla = Class.forName(className); return(Pet)cla.newInstance(); }catch(ClassNotFoundException e) { System.out.println("沒法識別您的標識!"); }catch(InstantiationException e) { e.printStackTrace(); }catch(IllegalAccessException e) { e.printStackTrace(); } returnnull; } } classPet {} classDogextendsPet {} classCatextendsPet {} classPenguinextendsPet {} conf/pet.properties文件內容以下: dog=demo08.Dog cat=demo08.Cat penguin=demo08.Penguin 這裏的配置文件爲.properties,稱做屬性文件。經過反射讀取裏邊的內容。這樣代碼是固定的,可是配置文件的內容咱們能夠改,這樣使咱們的代碼靈活了不少! 綜上JAVA反射的再次學習,靈活的運用它,可以使咱們的代碼更加靈活,可是它也有它的缺點,就是運用它會使咱們的軟件的性能下降,複雜度增長,因此還要咱們慎重的使用它。 更多內容關注微信公衆號mjw-java或訪問www.moliying.comjava

相關文章
相關標籤/搜索