【016期】JavaSE面試題(十六):反射

開篇介紹

你們好,我是Java最全面試題庫的提褲姐,今天這篇是JavaSE系列的第十六篇,主要總結了Java中反射相關的問題,在後續,會沿着第一篇開篇的知識線路一直總結下去,作到日更!若是我能作到百日百更,但願你也能夠跟着百日百刷,一百天養成一個好習慣。java

說說你對 Java 中反射的理解

在運行狀態,
對於任意一個類,都能獲取這個類的全部屬性和方法,
對任意一個對象,都能調用它的任意屬性和方法。
這種動態獲取的信息及動態調用對象的方法即爲Java的反射。面試

反射能作什麼

在運行時判斷一個類所具備的成員變量和方法
在運行時判斷任意一個對象所屬的類
在運行時構造一個類的對象
在運行時調用任意一個對象的方法編程

class.forName和classLoader的區別

class.forName:框架

  • 將類的.class文件加載到jvm中
  • 對類進行解釋,執行類中的static塊

classLoader:jvm

  • 只幹一件事情:將.class文件加載到jvm中,不會執行static中的內容,只有在newInstance纔會去執行static塊。

Class.forName(className):
內部調用的方法是 Class.forName(className,true,classloader);
第2個boolean參數表示類是否須要初始化, Class.forName(className)默認是須要初始化。
一旦初始化,就會觸發目標對象的static塊代碼執行,static參數也也會被再次初始化。spa

ClassLoader.loadClass(className):
內部調用的方法是ClassLoader.loadClass(className,false);
第2個 boolean參數,表示目標對象是否進行連接,false表示不進行連接,不進行連接意味着不進行包括初始化等一些列步驟,那麼靜態塊和靜態對象就不會獲得執行代理

動靜態代理的區別,什麼場景使用?

靜態代理一般只代理一個類,動態代理是代理一個接口下的多個實現類code

靜態代理事先知道要代理的是什麼,而動態代理不知道要代理什麼東西,只有在運行時才知道。對象

動態代理是實現 JDK 裏的 InvocationHandler 接口的 invoke 方法,但注意的是代理的是接口,也就是你的業務類必需要實現接口,經過 Proxy 裏的 newProxyInstance 獲得代理對象。
還有一種動態代理 CGLIB,代理的是類,不須要業務類繼承接口,經過派生的子類來實現代理。經過在運行時,動態修改字節碼達到修改類的目的。繼承

AOP 編程就是基於動態代理實現的,好比著名的 Spring 框架、Hibernate 框架等等都是動態代理的使用例子。

Java 的類加載器的種類都有哪些?

一、根類加載器(Bootstrap) --C++寫的 ,看不到源碼
二、擴展類加載器(Extension) --加載位置 :jre\lib\ext
三、系統(應用)類加載器(System\App) --加載位置 :classpath 中 四、自定義加載器(必須繼承 ClassLoader)

類何時被初始化?

  • 建立類的實例,也就是 new 一個對象
  • 訪問某個類或接口的靜態變量,或者對該靜態變量賦值
  • 調用類的靜態方法
  • 反射(Class.forName("com.hcx.load")
  • 初始化一個類的子類(會首先初始化子類的父類)
  • JVM 啓動時標明的啓動類,即文件名和類名相同的那個類

類的初始化步驟:

  • 若是這個類尚未被加載和連接,那先進行加載和連接
  • 假如這個類存在直接父類,而且這個類尚未被初始化(注意:在一個類加載器中,類只能初始化一次),那就初始化直接的父類(不適用於接口)
  • 加入類中存在初始化語句(如 static 變量和 static塊),那就依次執行這些初始化語句。

得到一個類對象有哪些方式?

  • 類型.class,例如:String.class
  • 對象.getClass(),例如:"hello".getClass()
  • Class.forName(),例如:Class.forName("java.lang.String")
相關文章
相關標籤/搜索