類加載過程的原理分析

異常錯誤java

Java.lang.ClassNotFoundExcetpion背後就涉及到了java技術體系中的類加載編程

概念數組

  1. 元信息: Class文件由類裝載器裝載後,在JVM中將造成一份描述Class結構的元信息對象,經過該元信息對象能夠獲知Class的結構信息:如構造函數,屬性和方法等,Java容許用戶藉由這個Class相關的元信息對象間接調用Class對象的功能
  2. 類加載機制:虛擬機把描述類的數據從class文件加載到內存,並對數據進行校驗,轉換解析和初始化,最終造成能夠被虛擬機直接使用的Java類型

存在引用多線程

那麼若是ClassA中引用了ClassB呢?當類加載器在加載ClassA的時候,發現引用了ClassB,此時類加載若是檢測到ClassB尚未被加載,則先回去加載.當ClassB加載完成後,繼續回來加載ClassA.換句話說,類會經過自身對應的來加載其加載其餘引用的類.jvm

肯定類的惟一性函數

JVM規定,對於任何一個類,都須要由加載它的類加載器和這個類自己一同確立在java虛擬機中的惟一性,通俗點就是說,在jvm中判斷兩個類是不是同一個類取決於類加載和類自己,也就是同一個類加載器加載的同一份Class文件生成的Class對象纔是相同的,類加載器不一樣,那麼這兩個類必定不相同.this

class對象的理解.net

  1. 類只是對事物的描述,而實例化就至關於爲這個描述新開闢了一塊內存,能夠改變這塊區域裏的各類屬性(成員變量)
  2. 在java裏,Class是一個實實在在的類,在包 java.lang 下,有這樣一個Class.java文件,它跟咱們本身定義的類同樣,是一個實實在在的類,Class對象就是這個Class類的實例了
  3. /*
    • Constructor. Only the Java Virtual Machine creates Class
    • objects. */ private Class() {}
  4. java.lang.Class類,這個類只能經過JVM來建立
  5. 在Java裏,全部的類的根源都是Object類,而Class也不例外,它是繼承自Object的一個特殊的類,它內部能夠記錄類的成員、接口等信息,也就是在Java裏,Class是一個用來表示類的類,Class是一個實實在在的類,能夠爲它建立實例
  6. Class對象,也被叫作Class類的實例 例如運行的程序有A、B、C三個類,那麼Class類就是對A、B、C三個類的抽象。所謂抽象,就是提取這些類的一些共同特徵,好比說這些類都有類名,都有對應的hashcode,還有其餘一些元數據
  7. 虛擬機爲每種類型管理一個獨一無二的Class對象。也就是說,每一個類(型)都有一個Class對象。運行程序時,Java虛擬機(JVM)首先檢查是否所要加載的類對應的Class對象是否已經加載。若是沒有加載,JVM就會根據類名查找.class文件,並將其Class對象載入。
  8. 基本的 Java 類型(boolean、byte、char、short、int、long、float 和 double)和關鍵字 void 也都對應一個 Class 對象。 每一個數組屬於被映射爲 Class 對象的一個類,全部具備相同元素類型和維數的數組都共享該 Class 對象
  9. 將某個類的class對象(描述這個類的類),而後將它載入到了內存中的時候,其他的全部的實例都是依照這個模版來建立的。總結起來在運行期間,若是咱們要產生某個類的對象,Java虛擬機(JVM)會檢查該類型的Class對象是否已被加載。若是沒有被加載,JVM會根據類的名稱找到.class文件並加載它。一旦某個類型的Class對象已被加載到內存,就能夠用它來產生該類型的全部對象
  10. Java程序在運行時每一個類都會對應一個Class對象,能夠從Class對象中獲得與類相關的信息,Class對象存儲在方法區(又名Non-Heap,永久代),當咱們運行Java程序時,若是加載的jar包很是多,大於指定的永久代內存大小時,則會報出PermGen錯誤,就是Class對象的總計大小,超過永久代內存的緣故。
  11. 獲取父類方法:getSuperclass() public native Class<? super T> getSuperclass(); 這是一個本地方法,這裏的邏輯有點饒,方法返回的是這個Class對象所表明的Java類的父類對應的的Class 對象。 例如: Thread.class.getSuperclass()將返回一個表明Thread類的Class對象,Thread.class.getSuperclass().toString()則輸出這個Class對象的字符串表示:classjava.lang.Object。其實這裏的關係無非就是說Thread的超類是Object

取得class類,而後實例化線程

有一個表明java.lang.Thread類的Class實例對象objec1,也就是說,泛型參數T此時就是Thread,object1這個實例表明Thread這個類。好了,如今調用object1的newInstance方法,即object1.newInstance(),此時這個調用將返回一個Thread類的對象。簡單驗證:code

 

    public class ForName {

 

    /**

        * @param args

     * @throwsIllegalAccessException

     * @throwsInstantiationException

     */

    public static void main(String[] args) throws InstantiationException, IllegalAccessException {

       Class<?> c = null ;

       try {

           c = Class.forName("java.lang.Thread");

       } catch (ClassNotFoundException e) {

           e.printStackTrace();

       }

       Thread thread = (Thread) c.newInstance(); //類型轉化一下

       System.out.println(thread.getId());

 

    } }

9. class類的方法和技巧

  1. . 一個Class對象描述了一個特定類的屬性,Class類中最經常使用的方法getName以 String 的形式返回此 Class 對象所表示的實體(類、接口、數組類、基本類型或 void)名稱
  2. . forName和newInstance結合起來使用,能夠根據存儲在字符串中的類名建立對象。例如 Object obj = Class.forName(s).newInstance();
  3. 虛擬機爲每種類型管理一個獨一無二的Class對象。所以可使用==操做符來比較類對象。例如: if(e.getClass() == Employee.class)...

java.lang包中的基礎類庫-object

  1. . Object沒有實現clone(),實現了hashCode(),哈希就是對象實例化後在堆內存的地址,用「==」比較兩個對象,實際就是比較的內存地址是不是一個,也就是hashCode()是否相等
  2. . 對象的equals()方法和==符號是同樣的,都是比較內存地址,可是有些對象重寫了equals()方法,好比String,使其達到比較內容是否相同的效果
  3. . 兩個方法wait()和notify()是和多線程編程相關的,多線程裏面synchronized實際就是加鎖,默認是用this當鎖,固然也能夠用任何對象當鎖,wait()上鎖,線程阻塞,notify()開鎖,收到這個通知的線程運行
相關文章
相關標籤/搜索