反射
在運作狀态中,擷取任意一個類的結構,建立對象,得到方法,執行方法,屬性。
類加載
三種類加載器:
- BoostrapClassLoader引導啟動類加載器;使用C++編寫主要加載/lib的類庫,無法被應用直接應用。
- ExtensionClassLoader擴充類加載器;主要加載/lib/ext類庫
- ApplicationClassLoader應用類加載器;加載classpath目錄下的所有jar和class檔案。
雙親委派、
進行類加載時,會轉發類加載請求到父類加載器,當父類加載器範圍内沒有這個類時回報給子類進行加載。(避免重複加載)。
反射中的構造方法
//加載類得到類對象
Class<User> aClass = (Class<User>) Class.forName("reflect.User");
//找到無參數構造方法
Constructor<User> constructor = aClass.getConstructor();
//使用公開無參數構造方法,建立對象
User user = constructor.newInstance();
//使用有公開參數構造方法獲得有參數對象
// Constructor<User> constructor1 = aClass.getConstructor(new Class[]{String.class, String.class});
// user = constructor1.newInstance("name", "sex");
//擷取所有權限的構造方法
Constructor<User> declaredConstructor1 = aClass.getDeclaredConstructor();
//擷取所有權限的構造方法數組
Constructor<User> declaredConstructor = aClass.getDeclaredConstructor(new Class[]{String.class, String.class});
//忽略權限檢查
declaredConstructor.setAccessible(true);
user = declaredConstructor.newInstance("yse", "nan");
System.out.println(user.toString());
反射中調用方法
//加載類
Class<User> aClass =(Class<User>) Class.forName("reflect.User");
//擷取類的構造方法
Constructor<User> declaredConstructor = aClass.getDeclaredConstructor();
//建立對象
User user = declaredConstructor.newInstance();
//通過反射擷取類的方法:參數1.方法名,2.傳入參數屬性
Method setName = aClass.getMethod("setName",String.class);
//1.哪個對象需要調用,2.傳遞的參數
setName.invoke(user,"帥哥");
System.out.println(user.toString());
//擷取所有權限的方法
Method setSex = aClass.getDeclaredMethod("setSex", String.class);
//允許私有通路
setSex.setAccessible(true);
//方法調用
setSex.invoke(user,"男");
System.out.println(user.toString());
反射得到類的屬性
//加載類
Class<User> aClass = (Class<User>) Class.forName("reflect.User");
//擷取無參數構造
Constructor<User> constructor = aClass.getConstructor();
//獲得對象
User user = constructor.newInstance();
//獲得所有權限的屬性(屬性名)
Field number = aClass.getDeclaredField("number");
//可以通路私有權限
number.setAccessible(true);
//1.需要改屬性的對象。2.改的參數
number.set(user,123);
System.out.println(user.toString());
反射操作注解
//加載類
Class aClass = Class.forName("annotation.Book");
//獲得注解類
TableAnnotation annotation =(TableAnnotation) aClass.getAnnotation(TableAnnotation.class);
//擷取所有權限屬性
Field[] fields = aClass.getDeclaredFields();
for (Field f:fields) {
//擷取屬性對應的注解
ColumnAnnotation annotation1 = f.getAnnotation(ColumnAnnotation.class);
System.out.println(f.getName()+annotation1.columnName());
}
内省-基于反射延伸的api(Instospector)
Bean類:
- 擁有無參數構造器
- 所有屬性私有并提供get/set方法
- 實作了序列化接口
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiNx8FesU2cfdGLwczX0xiRGZkRGZ0Xy9GbvNGL1EzXlpXazxSa2EWNhJTW1UUc1Ujc5RTNLFGN142UhVTQClGVF5UMR9Fd4VGdsATNfd3bkFGazxycykFaKdkYzZUbapXNXlleSdVY2pESa9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL4czM4ITNwEjM4ATOwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
擷取get和set方法
public static void main(String[] args) throws IntrospectionException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class c = User.class;
BeanInfo beanInfo = Introspector.getBeanInfo(c);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor p : propertyDescriptors) {
Method readMethod = p.getReadMethod();
Method writeMethod = p.getWriteMethod();
System.out.println(readMethod);
System.out.println(writeMethod);
}
}
運作結果
public final native java.lang.Class java.lang.Object.getClass()
null
public boolean fx.User.isFlag()
public void fx.User.setFlag(boolean)
public java.lang.String fx.User.getName()
public void fx.User.setName(java.lang.String)
public java.lang.String fx.User.getSex()
public void fx.User.setSex(java.lang.String)