學了Java這麼長時間,但是就是沒有學習反射和註解,因爲在我實際的編寫代碼的過程中還沒有用到,但是這學期我想學習Java流行的框架,所以回過頭來學習反射和註解的知識。
反射
一開始學習這個概念的時候就感覺沒有什麼用,經過一篇文章的講解,對於反射的應用大致有了瞭解。什麼是反射?平時我們都是由類取建造對象,反過來就是反射的概念了,由對象取尋找類對象。類對象,就是用於描述這種類,都有什麼屬性,什麼方法的
獲取類對象的三種方法:在JVM中,每一種類就只有一個類對象存在,所以class1和class2和class3相同
package reflection;
public class TextReflect {
public static void main(String[] args) {
try {
Class class1 = Class.forName("reflection.User");
System.out.println(class1);
Class class2 = User.class;
System.out.println(class2);
Class class3 = new User().getClass();
System.out.println(class3);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
當獲取類對象時候,會執行類中的靜態方法,我覺得就是獲取類對象就會執行類加載進JVM這個過程
那我們如何通過類對象來創建對象呢?
第一步:獲取類對象
第二步:獲取構造器對象
第三步:利用構造器對象獲取對象
package reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class TextRel2 {
public static void main(String[] args) {
try {
Class userClass = User.class;
Constructor[] constructors = userClass.getConstructors();
User user = (User) constructors[0].newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
這樣的作用是:假如給出一個配置文件,該文件中有一個類名,在測試文件中,只需要讀取文件中的類名即可創建出對象,要想創建其他對象,只需修改配置文件即可,不需要修改測試文件中的代碼。
除了上面的利用類對象創建對象的用法,類對象還可以修改對象屬性和使用對象方法
package reflection;
import java.lang.reflect.Field;
public class TextRel {
public static void main(String[] args) {
User user = new User();
user.setName("yzg");
user.setAge(20);
try {
Field name = user.getClass().getDeclaredField("name");
System.out.println(user.getName());
//因爲name是User中的私有屬性 聲明這個方法才能修改name的值
name.setAccessible(true);
//傳入的是一個對象和想要修改之後的值
name.set(user,"新修改的值");
System.out.println(user.getName());
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
getField和getDeclaredField的區別
這兩個方法都是用於獲取字段
getField 只能獲取public的,包括從父類繼承來的字段。
getDeclaredField 可以獲取本類所有的字段,包括private的,但是不能獲取繼承來的字段。
(注: 這裏只能獲取到private的字段,但並不能訪問該private字段的值,除非加上setAccessible(true))
package reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TextRel3 {
public static void main(String[] args) {
User user = new User();
user.setName("yzg");
try {
System.out.println(user.getName());
Method setName = user.getClass().getMethod("setName", String.class);
setName.invoke(user,"新修改的值");
System.out.println(user.getName());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
Method setName = user.getClass().getMethod("setName", String.class);
setName.invoke(user,"新修改的值");
這就是反射的大致內容,等學到後面的框架知識我在回來看看這個反射的知識,肯定會有更深的認識!
註解
初學註解,不知道註解到底可以幹什麼,不過我在網上發現一個比較好的文章,有興趣的可以看看,我覺得寫的挺好得!
我看了幾篇文章,裏面都提到了反射和註解在框架中能用到,所以等後面學習到框架得時候,再回來複習一遍!