天天看點

java的反射反射

反射

在運作狀态中,擷取任意一個類的結構,建立對象,得到方法,執行方法,屬性。

類加載

三種類加載器:

  1. BoostrapClassLoader引導啟動類加載器;使用C++編寫主要加載/lib的類庫,無法被應用直接應用。
  2. ExtensionClassLoader擴充類加載器;主要加載/lib/ext類庫
  3. 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類:

  1. 擁有無參數構造器
  2. 所有屬性私有并提供get/set方法
  3. 實作了序列化接口
java的反射反射
擷取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)