天天看點

Java充電站:Java反射常見面試題總結

1、什麼是Java反射機制?

Java的反射(reflection)機制是指在程式的運作狀态中,可以構造任意一個類的對象,可以了解任意一個對象所屬的類,可以了解任意一個類的成員變量和方法,可以調用任意一個對象的屬性和方法。 這種動态擷取程式資訊以及動态調用對象的功能稱為Java語言的反射機制。

1、除了使用new建立對象之外,還可以用什麼方法建立對象?

使用Java反射可以建立對象!

2、Java反射建立對象效率高還是通過new建立對象的效率高?

通過new建立對象的效率比較高。通過反射時,先找查找類資源,使用類加載器建立,過程比較繁瑣,是以效率較低

3、java反射的作用?

反射機制是在運作時,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意個對象,都能夠調用它的任意一個方法。在java中,隻要給定類的名字,就可以通過反射機制來獲得類的所有資訊。

這種動态擷取的資訊以及動态調用對象的方法的功能稱為Java語言的反射機制

  • 在運作時判定任意一個對象所屬的類
  • 在運作時構造任意一個類的對象
  • 在運作時判定任意一個類所具有的成員變量和方法
  • 在運作時調用任意一個對象的成員變量和 方法
  • 在運作調用任意一個對象的方法
  • 生成動态代碼

4、哪些地方會用到反射?

  1. JDBC中,利用反射動态加載資料庫驅動程式
  2. Web伺服器中利用反射調用Servlet的服務方法
  3. 架構用到反射機制,注入屬性,調用方法,如Spring

5、反射的實作方法?

  1. Class.forName(“類的路徑”)
  2. 類名.class
  3. 對象名.getClass()
  4. 基本類型的包裝類,可以調用包裝類的Type屬性來獲得該包裝類的Class對象

6、實作Java反射的類

  • Class:表示正在運作的Java應用程式中的類和接口

    注意: 所有擷取對象的資訊都需要Class類來實作。

  • Field:提供有關類和接口的屬性資訊,以及對它的動态通路權限。
  • Constructor:提供關于類的單個構造方法的資訊以及它的通路權限
  • Method:提供類或接口中某個方法的資訊

7、反射機制有哪些優缺點?

優點:
  • 能夠運作時動态擷取類的執行個體,提高靈活性;
  • 與動态編譯結合
缺點:
  • 使用反射性能較低,需要解析位元組碼,将記憶體中的對象進行解析。
解決方案:
  1. 通過setAccessible(true)關閉JDK的安全檢查來提升反射速度;
  2. 多次建立一個類的執行個體時,有緩存會快很多
  3. ReflflectASM工具類,通過位元組碼生成的方式加快反射速度
  4. 相對不安全,破壞了封裝性(因為通過反射可以獲得私有方法和屬性)

8、Java反射API

反射 API 用來生成 JVM 中的類、接口或則對象的資訊
  1. Class 類:反射的核心類,可以擷取類的屬性,方法等資訊。
  2. Field 類:Java.lang.reflec 包中的類,表示類的成員變量,可以用來擷取和設定類之中的屬性

    值。

  3. Method 類: Java.lang.reflec 包中的類,表示類的方法,它可以用來擷取類中的方法資訊或

    者執行方法。

  4. Constructor 類: Java.lang.reflec 包中的類,表示類的構造方法。

9、反射使用步驟(擷取 Class 對象、調用對象方法)

  1. 擷取想要操作的類的 Class 對象,他是反射的核心,通過 Class 對象我們可以任意調用類的方法。
  2. 調用 Class 類中的方法,既就是反射的使用階段。
  3. 使用反射 API 來操作這些資訊。

10、擷取 Class 對象有幾種方法

  1. 調用某個對象的 getClass()方法
Person p=new Person();
Class clazz=p.getClass();      
  1. 調用某個類的 class 屬性來擷取該類對應的 Class 對象
Class clazz=Person.class;      
  1. 使用 Class 類中的 forName()靜态方法(最安全/性能最好)
Class clazz=Class.forName("類的全路徑"); //最常用      
當我們獲得了想要操作的類的 Class 對象後,可以通過 Class 類中的方法擷取并檢視該類中的方法和屬性。
//擷取 Person 類的 Class 對象
Class clazz=Class.forName("reflection.Person");
//擷取 Person 類的所有方法資訊
Method[] method=clazz.getDeclaredMethods();
for(Method m:method){
    System.out.println(m.toString());
}
//擷取 Person 類的所有成員屬性資訊
Field[] field=clazz.getDeclaredFields();
for(Field f:field){
    System.out.println(f.toString());
}
//擷取 Person 類的所有構造方法資訊
Constructor[] constructor=clazz.getDeclaredConstructors();
for(Constructor c:constructor){
    System.out.println(c.toString());
}      

11、利用反射動态建立對象執行個體

  1. Class 對象的 newInstance()

    使用 Class 對象的 newInstance()方法來建立該 Class 對象對應類的執行個體,但是這種方法要求該 Class 對象對應的類有預設的空構造器。

  2. 調用 Constructor 對象的 newInstance()

    先使用 Class 對象擷取指定的 Constructor 對象,再調用 Constructor 對象的 newInstance()方法來建立 Class 對象對應類的執行個體,通過這種方法可以標明構造方法建立執行個體。

//擷取 Person 類的 Class 對象
Class clazz=Class.forName("reflection.Person");
//使用.newInstane 方法建立對象
Person p=(Person) clazz.newInstance();
//擷取構造方法并建立對象
Constructor c=clazz.getDeclaredConstructor(String.class,String.class,int.class);
//建立對象并設定屬性13/04/2018
Person p1=(Person) c.newInstance("李四","男",20);