這篇文章主要介紹“JDK中的反射有什么作用”,在日常操作中,相信很多人在JDK中的反射有什么作用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”JDK中的反射有什么作用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
在運行狀態中,我們可以根據“類的部分已知的信息
”來還原“類的全部的信息
”。
類名
類的對象
屬性
方法
繼承關系
Annotation注解
public class User implements Serializable{ private static final long serialVersionUID = 1510634274152200118L; private int id; private String passWord; public User() { System.out.println("Create user... "); } public User(int id, String passWord) { this.id = id; this.passWord = passWord; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } @Override public String toString() { return "User [id=" + id + ", passWord=" + passWord + "]"; } }
根據類名,構造類的代碼:
@Test public void testReflection() throws Exception { Class<?> clazz = Class.forName("test.User"); User user = (User) clazz.newInstance(); System.out.println("user = " + user); }
輸出:
Create user... user = User [id=0, passWord=null]
@Test public void testClazz() throws Exception { Class<?> clazz1 = Class.forName("test.User"); Class clazz2 = User.class; Class clazz3 = new User().getClass(); System.out.println("clazz1: " + clazz1); System.out.println("clazz2: " + clazz2); System.out.println("clazz3: " + clazz3); }
輸出:
Create user... clazz1: class test.User clazz2: class test.User clazz3: class test.User
構造函數
成員方法
成員變量
類的其它信息(如注解、包名、類名、繼承關系等等)
// 獲取“參數是parameterTypes”的public的構造函數 public Constructor getConstructor(Class[] parameterTypes) // 獲取全部的public的構造函數 public Constructor[] getConstructors() // 獲取“參數是parameterTypes”的,并且是類自身聲明的構造函數,包含public、protected和private方法。 public Constructor getDeclaredConstructor(Class[] parameterTypes) // 獲取類自身聲明的全部的構造函數,包含public、protected和private方法。 public Constructor[] getDeclaredConstructors() // 如果這個類是“其它類的構造函數中的內部類”,調用getEnclosingConstructor()就是這個類所在的構造函數;若不存在,返回null。 public Constructor getEnclosingConstructor()
測試:
@Test public void testConstructor() throws Exception { Class<?> clazz = Class.forName("test.User"); Constructor<?> constructor = clazz.getDeclaredConstructor(null); Object object1 = constructor.newInstance(); System.out.println(object1); Constructor<?> constructor2 = clazz.getDeclaredConstructor(new Class[] {int.class, String.class}); Object object2 = constructor2.newInstance(1, "123456"); System.out.println(object2); }
輸出:
Create user... User [id=0, passWord=null] User [id=1, passWord=123456]
可以調用默認的構造函數,也可以通過
clazz.getDeclaredConstructor(new Class[] {int.class, String.class})
來調用User的含參構造函數
public User(int id, String passWord) { this.id = id; this.passWord = passWord; }
// 獲取“名稱是name,參數是parameterTypes”的public的函數(包括從基類繼承的、從接口實現的所有public函數) public Method getMethod(String name, Class[] parameterTypes) // 獲取全部的public的函數(包括從基類繼承的、從接口實現的所有public函數) public Method[] getMethods() // 獲取“名稱是name,參數是parameterTypes”,并且是類自身聲明的函數,包含public、protected和private方法。 public Method getDeclaredMethod(String name, Class[] parameterTypes) // 獲取全部的類自身聲明的函數,包含public、protected和private方法。 public Method[] getDeclaredMethods() // 如果這個類是“其它類中某個方法的內部類”,調用getEnclosingMethod()就是這個類所在的方法;若不存在,返回null。 public Method getEnclosingMethod()
可以判斷類中是否含有某個方法,也可以調用類中的任何一個方法(包括私有方法)。
@Test public void testMethod() throws Exception { Class<?> clazz = Class.forName("test.User"); Method[] declaredMethods = clazz.getDeclaredMethods(); for (Method method : declaredMethods) { System.out.println(method); } System.out.println(); Method printInfo = clazz.getDeclaredMethod("printInfo", new Class[]{}); User user = (User) clazz.newInstance(); printInfo.invoke(user, null); }
輸出:
Create user... public java.lang.String test.User.toString() public int test.User.getId() public void test.User.printInfo() public void test.User.setId(int) public void test.User.setPassWord(java.lang.String) public java.lang.String test.User.getPassWord() User [id=0, passWord=null]
// 獲取“名稱是name”的public的成員變量(包括從基類繼承的、從接口實現的所有public成員變量) public Field getField(String name) // 獲取全部的public成員變量(包括從基類繼承的、從接口實現的所有public成員變量) public Field[] getFields() // 獲取“名稱是name”,并且是類自身聲明的成員變量,包含public、protected和private成員變量。 public Field getDeclaredField(String name) // 獲取全部的類自身聲明的成員變量,包含public、protected和private成員變量。 public Field[] getDeclaredFields()
@Test public void testField() throws Exception { Class<?> clazz = Class.forName("test.User"); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { System.out.println(field); } // 創建并通過反射,修改一個 private 變量 id User user = (User) clazz.newInstance(); Field field = clazz.getDeclaredField("id"); field.setAccessible(true); field.set(user, 123); user.printInfo(); }
輸出:
private static final long test.User.serialVersionUID private int test.User.id private java.lang.String test.User.passWord Create user... User [id=123, passWord=null]
我們可以看到,User中對于id的定義:
private int id;
而在測試用例中,可以獲取對象中私有的id變量,并直接修改內容,最終輸出的id=123。
// 獲取類的"annotationClass"類型的注解 (包括從基類繼承的、從接口實現的所有public成員變量) public Annotation<A> getAnnotation(Class annotationClass) // 獲取類的全部注解 (包括從基類繼承的、從接口實現的所有public成員變量) public Annotation[] getAnnotations() // 獲取類自身聲明的全部注解 (包含public、protected和private成員變量) public Annotation[] getDeclaredAnnotations()
// 獲取實現的全部接口 public Type[] getGenericInterfaces() // 獲取父類 public Type getGenericSuperclass()
到此,關于“JDK中的反射有什么作用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。