java類加載器,Java類加載器過程

本文目錄一覽:

Java:如何編寫自己的Java類加載器

給你簡單介紹一下類加載器

1.類加載器就加載位元組碼文件(.class)

public class FileClassLoader extends ClassLoader {    String rootDir=null;    public FileClassLoader(String rootDir) {        this.rootDir = rootDir;    }    @Override      protected Class? findClass(String className) throws ClassNotFoundException {        //首先檢查是否已經被加載了。        Class? c = findLoadedClass(className);        String path = rootDir + “/” + className.replace(‘.’, ‘/’) + “.class”;        if (c != null) {            return c;        } else {            /*雙親委託模式*/            ClassLoader loaderParent = this.getParent();            c = loaderParent.loadClass(className);            if (c != null) {                return c;            } else {                /*如果再不行的話,就再進行加載。因為位元組碼的本質就是一個位元組數組*/                InputStream is = null;                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();                try {                    is = new FileInputStream(path);                    byte[] buffer = new byte[1024];                    int len = 0;                    while ((len = is.read(buffer)) != -1) {                        outputStream.write(buffer, 0, len);                    }                    c = defineClass(className, buffer, 0, buffer.length);                }                catch (Exception e) {                    e.printStackTrace();                }                finally {                    if (is != null) {                        try {                            is.close();                        }                        catch (IOException e) {                            e.printStackTrace();                        }                    }                }            }            return c;        }    }

}

/*

相同的類加載器對同一個類進行加載,得到的hascode是相同的

 * 不同的類加載器對同一類進行加載,得到的hascode是不一樣的*/public class Demo {    public static void main(String[] args) {        FileClassLoader loader = new FileClassLoader(“c://myjava”);        FileClassLoader loader2=new FileClassLoader(“c://myjava”);        try {            Class? c = loader.findClass(“com.lg.test.HelloWorld”);            Class? c0=loader.findClass(“com.lg.test.HelloWorld”);            Class? c1=loader2.findClass(“com.lg.test.HelloWorld”);            Class? c2=loader.findClass(“com.lg.test.Demo01”);            Class? c3=loader.findClass(“java.lang.String”);            System.out.println(c.hashCode());            System.out.println(c.getClassLoader());            System.out.println(c0.hashCode());            System.out.println(c0.getClassLoader());            System.out.println(c1.hashCode());            System.out.println(c1.getClassLoader());            System.out.println(c2.hashCode());            System.out.println(c2.getClassLoader());            System.out.println(c3.hashCode());            System.out.println(c3.getClassLoader());        }        catch (ClassNotFoundException e) {            e.printStackTrace();        }    }}

java中class類中一個class對象獲取的類加載器在何

lang包。在java這個編譯語言中,class類中的一個class對象,其獲取的類加載器就位於lang包中,Java是一種面向對象的語言。

曲靖java培訓學校告訴你Java類加載機制?

每個開發人員對java.lang.ClassNotFoundExcetpion這個異常肯定都不陌生,這背後就涉及到了java技術體系中的類加載。Java的類加載機制是技術體系中比較核心的部分,雖然和大部分開發人員直接打交道不多,但是對其背後的機理有一定理解有助於排查程序中出現的類加載失敗等技術問題,對理解java虛擬機的連接模型和java語言的動態性都有很大幫助。電腦培訓就得好好的為大家介紹一下。

那麼什麼是類的加載?

類的加載指的是將類的.class文件中的二進制數據讀入到內存中,將其放在運行時數據區的方法區內,然後在堆區創建一個java.lang.Class對象,用來封裝類在方法區內的數據結構。類的加載的最終產品是位於堆區中的Class對象,Class對象封裝了類在方法區內的數據結構,並且向Java程序員提供了訪問方法區內的數據結構的接口。

Java類加載機制

類加載器是Java語言的一個創新,也是Java語言流行的重要原因之一。它使得Java類可以被動態加載到Java虛擬機中並執行。類加載器從JDK1.0就出現了,最初是為了滿足JavaApplet的需要而開發出來的。JavaApplet需要從遠程下載Java類文件到瀏覽器中並執行。現在類加載器在Web容器和OSGi中得到了廣泛的使用,而類加載器並不需要等到某個類被「首次主動使用」時再加載它,JVM規範允許類加載器在預料某個類將要被使用時就預先加載它,如果在預先加載的過程中遇到了.class文件缺失或存在錯誤,類加載器必須在程序首次主動使用該類時才報告錯誤(LinkageError錯誤)如果這個類一直沒有被程序主動使用,那麼類加載器就不會報告錯誤。

類的生命周期

類加載的過程中包括有加載,驗證,準備,解析,初始化五個階段。而需要注意的是在這五個階段中,加載、驗證、準備和初始化這四個階段發生的順序是確定的,而解析階段則不一定,它在某些情況下可以在初始化階段之後開始,這是為了支持Java語言的運行時綁定(也成為動態綁定或晚期綁定)。另外注意這裡的幾個階段是按順序開始,而不是按順序進行或完成,因為這些階段通常都是互相交叉地混合進行的,通常在一個階段執行的過程中調用或激活另一個階段。

java中類加載器是怎麼工作的

JVM將類加載過程分為三個步驟:裝載(Load),鏈接(Link)和初始化(Initialize)

鏈接又分為三個步驟,驗證、準備、解析

1) 裝載:查找並加載類的二進制數據;

2)鏈接:

驗證:確保被加載類的正確性;

準備:為類的靜態變量分配內存,並將其初始化為默認值;

解析:把類中的符號引用轉換為直接引用;

3)初始化:為類的靜態變量賦予正確的初始值;

那為什麼我要有驗證這一步驟呢?首先如果由編譯器生成的class文件,它肯定是符合JVM位元組碼格式的,但是萬一有高手自己寫一個class文件,讓JVM加載並運行,用於惡意用途,就不妙了,因此這個class文件要先過驗證這一關,不符合的話不會讓它繼續執行的,也是為了安全考慮吧。

準備階段和初始化階段看似有點牟盾,其實是不牟盾的,如果類中有語句:private static int a = 10,它的執行過程是這樣的,首先位元組碼文件被加載到內存後,先進行鏈接的驗證這一步驟,驗證通過後準備階段,給a分配內存,因為變量a是static的,所以此時a等於int類型的默認初始值0,即a=0,然後到解析(後面在說),到初始化這一步驟時,才把a的真正的值10賦給a,此時

java類加載器有幾種???

Java中加載器的種類大致可以分為四種:Bootstrap ClassLoader(由C++語言寫成),系統加載器(也就是內部類AppClassLoader),ExtClassLoader,以及java.net.UrlClassLoader.

當我們運行一個程序時,首先是找到JDK安裝目下的jvm.dll來啟動JAVA虛擬機,而後Bootstrap ClassLoader產生,接下來就是Bootstrap ClassLoader來加載ExtClassLoader,並且指定ExtClassLoader的父加載器為Bootstrap ClassLoader,但是因為Bootstrap ClassLoader用C++語言寫的,所以用JAVA的觀點來看,這個加載器的實例是不存在的,所以ExtClassLoader的父加載器被設置為了null,然後就是Bootstrap ClassLoader將AppClassLoader裝載,並指定其父加載器為ExtClassLoader。

JAVA是按照加載器的委派模型來實現的。這種模型是JAVA安全性機制的保證。並且值得我們注意的就是這幾個加載器的默認加載類的路徑。對於AppCLassLoder來說,它的路徑也就是我們的classpath裏面的路徑。而對於ExtClassLoader來說,它的路徑是jre\lib\ext\classes.對於URLClassLoader來說,它的加載路徑是我們指定的url。

北大青鳥java培訓:Tomcat的類加載器架構?

主流的Web服務器(也就是Web容器),如Tomcat、Jetty、WebLogic、WebSphere或其他筆者沒有列舉的服務器,都實現了自己定義的類加載器(一般都不止一個)。

因為一個功能健全的Web容器,要解決如下幾個問題:1)部署在同一個Web容器上的兩個Web應用程序所使用的類庫可以實現相互隔離。

這是最基本的需求,兩個不同的應用程序可能會依賴同一個第三方類庫的不同版本,不能要求一個類庫在一個服務器中只有一份,服務器應當保證兩個應用程序的類庫可以互相獨立使用。

2)部署在同一個Web容器上的兩個Web應用程序所使用的類庫可以互相共享。

這個需求也很常見,例如,用戶可能有10個使用Spring組織的應用程序部署在同一台服務器上,如果把10份Spring分別存放在各個應用程序的隔離目錄中,將會是很大的資源浪費——這主要倒不是浪費磁盤空間的問題,而是指類庫在使用時都要被加載到Web容器的內存,如果類庫不能共享,虛擬機的方法區就會很容易出現過度膨脹的風險。

3)Web容器需要儘可能地保證自身的安全不受部署的Web應用程序影響。

目前,有許多主流的Web容器自身也是使用語言來實現的。

因此,Web容器本身也有類庫依賴的問題,一般來說,基於安全考慮,容器所使用的類庫應該與應用程序的類庫互相獨立。

4)支持JSP應用的Web容器,大多數都需要支持HotSwap功能。

我們知道,JSP文件最終要編譯成Class才能由虛擬機執行,但JSP文件由於其純文本存儲的特性,運行時修改的概率遠遠大於第三方類庫或程序自身的Class文件。

而且ASP、PHP和JSP這些網頁應用也把修改後無須重啟作為一個很大的「優勢」來看待,因此「主流」的Web容器都會支持JSP生成類的熱替換,當然也有「非主流」的,如運行在生產模式(ProductionMode)下的WebLogic服務器默認就不會處理JSP文件的變化。

由於存在上述問題,在部署Web應用時,單獨的一個ClassPath就無法滿足需求了,所以各種Web容都「不約而同」地提供了好幾個ClassPath路徑供用戶存放第三方類庫,這些路徑一般都以「lib」或「classes」命名。

被放置到不同路徑中的類庫,河南電腦培訓認為具備不同的訪問範圍和服務對象,通常,每一個目錄都會有一個相應的自定義類加載器去加載放置在裏面的類庫。

現在,就以Tomcat容器為例,看一看Tomcat具體是如何規劃用戶類庫結構和類加載器的。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/249086.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 13:31
下一篇 2024-12-12 13:31

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • QML 動態加載實踐

    探討 QML 框架下動態加載實現的方法和技巧。 一、實現動態加載的方法 QML 支持從 JavaScript 中動態指定需要加載的 QML 組件,並放置到運行時指定的位置。這種技術…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發佈。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字符串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字符串中是否存在多個指定字符: 一、字符串遍歷 字符串是Java編程中非常重要的一種數據類型。要判斷字符串中是否存在多個指定字符…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29

發表回復

登錄後才能評論