1. 程式人生 > >JAVA中的反射

JAVA中的反射

new instance ron rip 數據類型 sse anti sar 動態調用

反射機制是什麽

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中的反射