您好,登錄后才能下訂單哦!
本文章向大家介紹如何在java項目中實現一個反射應用的基本知識點總結和需要注意事項,具有一定的參考價值,需要的朋友可以參考一下。
Java是一門面向對象編程語言,可以編寫桌面應用程序、Web應用程序、分布式系統和嵌入式系統應用程序。
創建一個Student類出來。注意類中的成員變量、構造方法、成員方法公共還是私有
package com.reflect; public class Student { //成員變量 public String name;//公共 private int age;//私有 //構造方法 public Student() { super(); // TODO Auto-generated constructor stub } //私有構造方法 private Student(String name) { this.name = name; } public Student(String name, int age) { super(); this.name = name; this.age = age; } //成員方法(getXxx/setXxx) public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //成員方法 public void study() { System.out.println("我愛學習java!"); } // 私有 private void study(String string) { System.out.println("我還愛學習"+string); } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }
反射概述
1、反射:反射是通過class文件對象,去使用文件對象的成員方法、構造方法、成員變量
回想之前我們使用對象方法時必須通過new對象去使用。new Student().study(),此時我們就發現了一個問題,小例中我們肯定是知道Student類中是有study()方法的,如果我們想使用用這個類但卻不清楚類中的信息,此時反射就起到了一定作用。
其實反射的作用,不止這一點點。如下
2、反射可以提高程序的靈活性和擴展性,降低耦合性,提高自適應能力。它允許程序創建和控制任何類的對象,無需提高硬編碼目標類
Java反射技術應用領域很廣,后期如軟件測試、JavaBean等都有很重要的作用
許多流行的開源框架例如Struts、Hibernate、Spring在實現過程中都采用了該技術
3、性能問題:使用反射基本上是一種解釋操作,用于字段和方法接入時要遠慢于直接代碼。因此Java反射機制只要應用在對;靈活性和擴展性要求很高的系統框架上,普通程序不建議使用使用反射會模糊程序內部邏輯:程序員希望在代碼中看到程序的邏輯,反射等繞過了源代碼的技術,因而會帶來維護問題。
反射獲取Class類對象
要想使用反射,我們必須得到class文件對象,也就是我們要使用的類Class對象
三種獲得class文件對象的方法:
Object類的getClass()方法
數據類型的靜態屬性class
Class類中的靜態方法public static Class forName(String classname)
一般我們使用第三種
package com.reflect; public class Demo { public static void main(String[] args) throws ClassNotFoundException { // 方式1 Student p = new Student(); Class c = p.getClass(); Student p2 = new Student(); Class c2 = p2.getClass(); System.out.println(p == p2);// false不是同一Student對象 System.out.println(c == c2);// true是同一class對象 // 方式2 Class c3 = Student.class; System.out.println(c == c3);//true是同一class對象 // 方式3 // ClassNotFoundException(類找不到時) Class c4 = Class.forName("com.reflect.Student"); System.out.println(c == c4);//true是同一class對象 } }
Class類中相關的幾個類
和成員變量有關 Field
和構造方法有關 Constructor
和成員方法有關 Method
有關的幾個方法
public T newInstance(Object… initargs) 使用此 Constructor 對象表示的構造方法來創建該構造方法的聲明類的新實例,并用指定的初始化參數初始化該實例。
反射獲取構造方法
先來認識幾個方法
public Constructor getConstructor()// 公共構造方法對象 public Constructor[] getConstructors()//所有公共構造方法對象 public Constructor[] getDeclaredConstructors()//所有構造方法對象 public Constructor getDeclaredConstructor()//獲取私有構造方法對象 public Constructor<T> getConstructor(Class<?>... parameterTypes)// 參數表示的是:你要獲取的構造方法的構造參數個數及數據類型的class字節碼文件對象 public void setAccessible(boolean flag)// 值為true則指示反射的對象在使用時應該取消Java語言訪問檢查。 暴力訪問
package com.reflect; import java.lang.reflect.Constructor; public class ConstructorDemo { public static void main(String[] args) throws Exception { // 獲取字節碼文件對象 Class c = Class.forName("com.reflect.Student"); // 獲取所有構造方法 Constructor[] cons = c.getDeclaredConstructors(); for (Constructor con : cons) { System.out.println(con); } // 獲取單個構造方法 Constructor con = c.getConstructor();// 返回的是構造方法對象 Constructor con1 = c.getConstructor(String.class, int.class);// 返回的是有參構造方法對象 Constructor con2 = c.getDeclaredConstructor(String.class); //創建對象 Object obj = con.newInstance(); Object obj1=con1.newInstance("小米",12); // 暴力訪問 con2.setAccessible(true);// 值為true則指示反射的對象在使用時應該取消Java語言訪問檢查。 Object obj2 = con2.newInstance("小白"); System.out.println(obj.toString()); System.out.println(obj1.toString()); System.out.println(obj2.toString()); } }
運行結果:
反射獲取成員變量
**類比上面Constructor類中的方法,這個類也有同樣的方法,獲取所有成員變量(返回數組),獲取私有成員變量等 這里不再贅述 **
package com.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; /* * 通過發生獲取成員變量并使用 */ public class FieldDemo { public static void main(String[] args) throws Exception { // 獲取字節碼文件對象 Class c = Class.forName("com.reflect.Student"); // 獲取所有的成員變量 Field[] fields = c.getFields(); Field[] fields1 = c.getDeclaredFields(); for (Field field : fields1) { System.out.println(field); } /* * Person p = new Person(); p.address = "北京"; System.out.println(p); */ // 通過無參構造方法創建對象 Constructor con = c.getConstructor(); Object obj = con.newInstance(); System.out.println(obj); // 獲取單個的成員變量 //通過成員變量名 Field nameField = c.getField("name"); // public void set(Object obj,Object value) // 將指定對象變量上此 Field 對象表示的字段設置為指定的新值。 nameField.set(obj, "小紅"); // 給obj對象的addressField字段設置值為"北京" System.out.println(obj); // 獲取age并對其賦值 // NoSuchFieldException 私有變量 Field ageField = c.getDeclaredField("age"); // IllegalAccessException 暴力訪問 ageField.setAccessible(true); ageField.set(obj, 18); System.out.println(obj); } }
運行結果:
反射獲取成員方法
**類比上面Constructor類中的方法,這個類也有同樣的方法,獲取所有成員方法(返回數組),獲取私有成員方法等 這里不再贅述 **
package com.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class MethodDemo { public static void main(String[] args) throws Exception { // 獲取字節碼文件對象 Class c = Class.forName("com.reflect.Student"); // 獲取所有的方法 Method[] methods = c.getMethods(); // 獲取自己的包括繼承父親的公共方法 Method[] methods1 = c.getDeclaredMethods(); // 獲取自己的所有的方法 for (Method method : methods1) { System.out.println(method); } Constructor con = c.getConstructor(); Object obj = con.newInstance(); // 獲取單個方法并使用 // public void show() // public Method getMethod(String name,Class<?>... parameterTypes) // 第一個參數表示的方法名,第二個參數表示的是方法的參數的class類型 Method m1 = c.getMethod("study"); // public Object invoke(Object obj,Object... args) // 返回值是Object接收,第一個參數表示對象是誰,第二參數表示調用該方法的實際參數 m1.invoke(obj); // 調用obj對象的m1方法 System.out.println("----------"); Method m2 = c.getDeclaredMethod("study", String.class); // NoSuchMethodException 訪問私有方法 暴力訪問 m2.setAccessible(true); m2.invoke(obj, "數學"); } }
運行結果:
以上就是小編為大家帶來的如何在java項目中實現一個反射應用的全部內容了,希望大家多多支持億速云!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。