JAVA中的反射
反射機制是什麽
Java反射指的是在運行狀態時,能夠獲取類的屬性和方法或者修改類運行時行為的過程。
java.lang.Class類提供了很多方法用於獲取元數據、檢查和改變類運行時的行為。
Java的反射主要涉及java.lang和java.lang.reflect包下的類。
反射機制能做什麽
反射機制主要提供了以下功能:
- 在運行時判斷任意一個對象所屬的類;
- 在運行時構造任意一個類的對象;
- 在運行時判斷任意一個類所具有的成員變量和方法;
- 在運行時調用任意一個對象的方法;
- 生成動態代理。
JDK為我們提供了那些反射機制中的類:
java.lang.Class; java.lang.reflect.Constructor; java.lang.reflect.Field; java.lang.reflect.Method; java.lang.reflect.Modifier;
反射的使用
通過反射機制動態一個對象獲得完整的包名和類名
java.lang.Class類
java.lang.Class主要提供了以下兩個功能:
- 提供方法用於訪問運行期間類的元數據;
- 提供方法用於檢查和修改類的運行時行為;
怎樣獲取Class對象
有三種方式,如下:
Class類的forName()方法,動態加載,運行時,開始裝入類, 並做類的靜態初始化
對象的getClass()方法,靜態加載(編譯時已加載)
.class語法, 靜態加載(編譯時已加載)
java.lang.Class類常用方法
Method |
Description |
1) public String getName() |
返回類名 |
2) public static Class forName(String className)throws ClassNotFoundException |
加載類並返回Class對象 |
3) public Object newInstance()throws InstantiationException,IllegalAccessException |
創建實例對象 |
4) public boolean isInterface() |
判斷是否是接口 |
5) public boolean isArray() |
判斷是否是數組 |
6) public boolean isPrimitive() |
判斷是否是原始數據類型 |
7) public Class getSuperclass() |
返回父類Class引用 |
8) public Field[] getDeclaredFields()throws SecurityException |
返回類的成員屬性字段數組 |
9) public Method[] getDeclaredMethods()throws SecurityException |
返回類的方法數組 |
10) public Constructor[] getDeclaredConstructors()throws SecurityException |
返回類的構造方法數組 |
11) public Method getDeclaredMethod(String name,Class[] parameterTypes)throws NoSuchMethodException,SecurityException |
返回類中指定參數類型的方法 |
public static void main(String[] args) throws Exception{ Class<?> clazz = ArrayList.class; System.out.println("className = "+clazz.getName()); System.out.println("is interface = " + clazz.isInterface()); System.out.println("is array = " + clazz.isArray()); // 獲取父類的Class對象 Class<?> superClass = clazz.getSuperclass(); //獲取類實現的接口 Class<?> [] interfaces = clazz.getInterfaces(); //獲取本類所定義的所有屬性,不包含父類屬性 Field []fileds = clazz.getDeclaredFields(); //獲取類所定義的所有屬性,包含父類的屬性 fileds = clazz.getFields(); //根據屬性名稱獲取屬性,不會從父類獲取,若當前類沒有則返回null Field ageFiled = clazz.getDeclaredField("age"); //根據屬性名稱獲取屬性,如果父類有也會返回 ageFiled = clazz.getField("age"); //獲取本類所定義的所有的方法,不包含父類 Method []ms = clazz.getDeclaredMethods(); //獲取類所定義的所有的方法,包含父類的方法 ms = clazz.getMethods(); //根據方法名和方法參數獲取方法,不包含父類 Method m = clazz.getDeclaredMethod("add",Object.class); //根據方法名和方法參數獲取方法,包含父類 m = clazz.getMethod("add",Object.class); //獲取所有構造方法 Constructor<?> []cons = clazz.getConstructors(); //根據參數類型獲取指定的構造方法 Constructor<?> con = clazz.getConstructor(int.class); }
動態調用構造方法創建對象
public static void main(String[] args) throws Exception{ Class<?> clazz = ArrayList.class; //調用不帶參數的構造方法創建對象 List list = (List)clazz.newInstance(); //調用int類型的參數創建對象 //先獲取到構造方法 Constructor<?> cons = clazz.getConstructor(int.class); list = (List) cons.newInstance(10); }
動態的操作屬性
public static void main(String[] args) throws Exception{ //動態創建一個對象 System.out.println(Human.class.getName()); Object h = Class.forName("com.deng.Human").newInstance(); //找到name屬性 Class<?> clazz = h.getClass(); Field f = clazz.getDeclaredField("name"); //若屬性是private的,則必須要設置其可訪問,才可以設置和取值 //若是非private的,則不需要 f.setAccessible(true); //設置屬性 f.set(h, "張三"); //獲取屬性的值 System.out.println(f.get(h)); }
動態調用方法:
JAVA中的反射