JavaSE面試題:反射

千鋒Python唐小強發表於2020-07-17

說說你對 Java 中反射的理解

在執行狀態,對於任意一個類,都能獲取這個類的所有屬性和方法,對任意一個物件,都能呼叫它的任意屬性和方法。這種動態獲取的資訊及動態呼叫物件的方法即為Java的反射。

反射能做什麼

在執行時判斷一個類所具有的成員變數和方法在執行時判斷任意一個物件所屬的類在執行時構造一個類的物件在執行時呼叫任意一個物件的方法

class.forName和classLoader的區別

class.forName:

  • 將類的.class檔案載入到jvm中
  • 對類進行解釋,執行類中的static塊

classLoader:

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

Class.forName(className):內部呼叫的方法是 Class.forName(className,true,classloader);第2個boolean參數列示類是否需要初始化, Class.forName(className)預設是需要初始化。一旦初始化,就會觸發目標物件的static塊程式碼執行,static引數也也會被再次初始化。

ClassLoader.loadClass(className):內部呼叫的方法是ClassLoader.loadClass(className,false);第2個 boolean引數,表示目標物件是否進行連結,false表示不進行連結,不進行連結意味著不進行包括初始化等一些列步驟,那麼靜態塊和靜態物件就不會得到執行

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

靜態代理通常只代理一個類,動態代理是代理一個介面下的多個實現類。

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

動態代理是實現 JDK 裡的 InvocationHandler 介面的 invoke 方法,但注意的是代理的是介面,也就是你的業務類必須要實現介面,透過 Proxy 裡的 newProxyInstance 得到代理物件。還有一種動態代理 CGLIB,代理的是類,不需要業務類繼承介面,透過派生的子類來實現代理。透過在執行時,動態修改位元組碼達到修改類的目的。

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

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

1、根類載入器(Bootstrap) --C++寫的 ,看不到原始碼

2、擴充套件類載入器(Extension) --載入位置 :jre\lib\ext 中

3、系統(應用)類載入器(System\App) --載入位置 :classpath 中

4、自定義載入器(必須繼承 ClassLoader)

類什麼時候被初始化?

  • 建立類的例項,也就是 new 一個物件
  • 訪問某個類或介面的靜態變數,或者對該靜態變數賦值
  • 呼叫類的靜態方法
  • 反射(Class.forName("com.hcx.load"))
  • 初始化一個類的子類(會首先初始化子類的父類)
  • JVM 啟動時標明的啟動類,即檔名和類名相同的那個類

類的初始化步驟:

  • 如果這個類還沒有被載入和連結,那先進行載入和連結
  • 假如這個類存在直接父類,並且這個類還沒有被初始化(注意:在一個類載入器中,類只能初始化一次),那就初始化直接的父類(不適用於介面)
  • 加入類中存在初始化語句(如 static 變數和 static塊),那就依次執行這些初始化語句。

獲得一個 物件有哪些方式?

  • 型別.class,例如:String.class
  • 物件.getClass(),例如:"hello".getClass()
  • Class.forName(),例如:Class.forName("java.lang.String")
JavaSE面試題:反射


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69923331/viewspace-2705044/,如需轉載,請註明出處,否則將追究法律責任。

相關文章