日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

java类加载的表现形式

發布時間:2023/11/27 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java类加载的表现形式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
java中的類是動態加載的,我們先看一下我們常用的類加載方式,先有一個感性的認識,才能進一步

  深入討論,類加載無非就是下面三種方式。

  class A{}

  class B{}

  class C{}

  public class Loader{

  public static void main(String[] args) throws Exception{

  Class aa=A.class;

  Class bb=Class.forName("B");

  Class cc=ClassLoader.getSystemClassLoader().loadClass("C");

  }

  }

  我們先看.class字面量方式,很多人可能不知道這種方式,因為這種用法不是一般java語法。

  通過javap我們可以發現,這種方式的大致等價于定義了一個靜態成員變量

  static Class class$0;(后面的編號是增長的)

  你可以試圖再定義一個 static Class class$0,應該會收到一個編譯錯誤(重復定義)。

  Class aa=A.class;

  就相當于

  if(class$0==null){

  try{

  Class.forName("A");

  }

  cacth(ClassNotFoundException e){

  throw new NoClassDefFoundError(e);

  }

  }

  Class aa=class$0;

  可以很清楚的看到,這種類的字面量定義其實不是加載類的方式,而是被編譯器處理了,實質上是使用了Class.forName方法,但是使用這種方式有一個很大的好處就是不用處理異常,因為編譯器處理的時候如果找不到類會拋出一個NoClassDefFoundError.也許你覺得需要處理 ClassNotFoundException這種異常,事實上99%的情況下我們可以把這種異常認為是一個錯誤。

  所以大部分情況我們使用這種方式會更簡潔。

  最常用的方式就是Class.forName方式了,這也是一個通用的上層調用。這個方法有兩個重載,可能很多人都忽略了第二個方法。

  public static Class forName(String name) throws ClassNotFoundException

  public static Class forName(String name, boolean initialize,ClassLoader loader) throws ClassNotFoundException

  第二個方法后面多了兩個參數,第二個參數表示是否初始化,第三個參數為指定的類加載器。

  在上面的例子中:

  Class bb=Class.forName("B");

  等價于

  Class bb=Class.forName("B",true,Loader.class.getClassLoader());

  這里要詳細說一下這個類的初始化這個參數,如果這個參數為false的話,類中的static成員不會被初始化,static語句塊也不會被執行。

  也就是類雖然被加載了,但是沒有被初始化,不過在第一次使用時仍然會初始化。

  所以我們有時候會看到Class.forName("XXX")。newInstance()這樣的語句,為什么這里要創建一個不用的實例呢?不過是為了保證類被初始化(兼容以前的系統)。

  其實第二個方法是比較難用的,需要指定類加載器,如果不指定而且又沒有安裝安全管理器的化,是無法加載類的,只要看一下具體的實現就明白了。

  最本質的方式當然是直接使用ClassLoader加載了,所有的類最終都是通過ClassLoader加載的,Class cc=ClassLoader.getSystemClassLoader()。loadClass("C");這里通過使用系統類加載器來加載某個類,很直接的方式,但是很遺憾的是通過這種方式加載類,類是沒有被初始化的(也就是初始化被延遲到真正使用的時候)。不過我們也可以借鑒上面的經驗,加載后實例化一個對象Class cc=ClassLoader.getSystemClassLoader()。loadClass("C")。newInstance()。

  這里使用了系統類加載器,也是最常用的類加載器,從classpath中尋找要加載的類。

  java中默認有三種類加載器:引導類加載器,擴展類加載器,系統類加載器。

  java中的類加載有著規范的層次結構,如果我們要了解類加載的過程,需要明確知道哪個類被誰加載,某個類加載器加載了哪些類等等,就需要深入理解ClassLoader的本質。

  以上只是類加載的表面的東西,我們還將討論深層次的東西。

轉載于:https://www.cnblogs.com/yongwnet/archive/2010/07/15/1778391.html

總結

以上是生活随笔為你收集整理的java类加载的表现形式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。