java類載入的順序
Ⅰ java程序運行的五個步驟
1、Java程序從源文件創建到程序運行要經過兩大步驟:1、源文件由編譯器編譯成位元組碼(ByteCode) 2、位元組碼由java虛擬機解釋運行。因為java程序既要編譯同時也要經過JVM的解釋運行,所以說Java被稱為半解釋語言("semi-interpreted" language)。
第一步(編譯): 創建完源文件之後,程序會先被編譯為.class文件。Java編譯一個類時,如果這個類所依賴的類還沒有被編譯,編譯器就會先編譯這個被依賴的類,然後引用,否則直接引用,這個有點像make。如果java編譯器在指定目錄下找不到該類所其依賴的類的.class文件或者.java源文件的話,編譯器話報「cant find symbol」的錯誤。
編譯後的位元組碼文件格式主要分為兩部分:常量池和方法位元組碼。常量池記錄的是代碼出現過的所有token(類名,成員變數名等等)以及符號引用(方法引用,成員變數引用等等);方法位元組碼放的是類中各個方法的位元組碼。
第二步(運行):java類運行的過程大概可分為兩個過程:1、類的載入 2、類的執行。需要說明的是:JVM主要在程序第一次主動使用類的時候,才會去載入該類。也就是說,JVM並不是在一開始就把一個程序就所有的類都載入到內存中,而是到不得不用的時候才把它載入進來,而且只載入一次。
2、下面是程序運行的詳細步驟:
在編譯好java程序得到Main.class文件後,在命令行上敲java Main。系統就會啟動一個jvm進程,jvm進程從classpath路徑中找到一個名為Main.class的二進制文件,將Main的類信息載入到運行時數據區的方法區內,這個過程叫做Main類的載入。
然後JVM找到Main的主函數入口,開始執行main函數。
main函數的第一條命令是Animal animal = new Animal("Puppy");就是讓JVM創建一個Animal對象,但是這時候方法區中沒有Animal類的信息,所以JVM馬上載入Animal類,把Animal類的類型信息放到方法區中。
載入完Animal類之後,Java虛擬機做的第一件事情就是在堆區中為一個新的Animal實例分配內存, 然後調用構造函數初始化Animal實例,這個Animal實例持有著指向方法區的Animal類的類型信息(其中包含有方法表,java動態綁定的底層實現)的引用。
當使用animal.printName()的時候,JVM根據animal引用找到Animal對象,然後根據Animal對象持有的引用定位到方法區中Animal類的類型信息的方法表,獲得printName()函數的位元組碼的地址。
開始運行printName()函數。
Ⅱ java類載入問題。不要告訴我結果,我問的是為什麼會是這樣的結果,載入順序是什麼
載入類、 靜態成員變數初始化、 靜態代碼塊、非靜態成員變數初始化、 構造方法;
首先 載入類的時候先載入類的靜態成員變數. 因為靜態變數依賴類,不依賴對象,先載入
public static int k = 0;
public static T t1 = new T("t1"); 載入到這一行的時候就會new一個對象出來,並執行public int j = print("j"); 因為j是成員變數,依賴對象.
所以在對象初始化的時候才載入. 然後載入非靜態的構造塊 構造方法. t2靜態變數同理.
t1 t2載入的時候,i n 並未初始化.因為靜態變數i , n 在靜態變數t1,t2後,所以i, n 就為0開始.
public static int i = print("i"); 載入到靜態變數i時,執行print方法.
當所有靜態變數載入完成後,載入靜態塊.
類的載入和對象的初始化是不一樣的.
Ⅲ java 類載入先後順序
父類態代碼塊
父類靜態屬性
//以上根據代碼順序
子類靜態屬性
子類靜態代碼塊
//以上根據代碼順序
父類屬性
父類代碼塊
//以上根據代碼順序
父類構造器
子類屬性
子類代碼塊
//以上根據代碼順序
子類構造方法
子類方法
父類方法
父類靜態方法
子類靜態方法
package com.zz;
/**
* Created by @摩西摩西 2020/3/21 22:29
**/
public class Father {
public String name=Son.getmetod("父類屬性");
public Father(){
System.out.println("父類構造器");
}
{
System.out.println("父類代碼塊");
}
public void fatherMethod(){
System.out.println("父類方法");
}
static {
System.out.println("父類態代碼塊");
}
static String name1=Son.getmetod("父類靜態屬性");
public static void fatherStaticMethod(){
System.out.println("父類靜態方法");
}
}
package com.zz;
/**
* Created by @摩西摩西 2020/3/21 22:32
**/
public class Son extends Father {
public String name = getmetod("子類屬性");
public Son() {
System.out.println("子類構造方法");
}
{
System.out.println("子類代碼塊");
}
public void sonMethod(){
System.out.println("子類方法");
}
public static String name1 = getmetod("子類靜態屬性");
static {
System.out.println("子類靜態代碼塊");
}
public static void sonStaticMethod() {
System.out.println("子類靜態方法");
}
public static String getmetod(String s) {
System.out.println(s);
return s;
}
public static void main(String[] args) {
Son son= new Son();
son.sonMethod();
son.fatherMethod();
fatherStaticMethod();
sonStaticMethod();
}
}
Ⅳ java的類載入器有哪些,它們的順序是什麼
類載入器有四種,分別是 bootstrapClassLoader (主要載入java核心api) , ExtClassLoaders是擴展類的類載入器,AppClassLoader 程序類載入器,還有一個是用戶繼承ClassLoader重寫的類載入器。
Ⅳ JVM之class載入過程
java虛擬機把描述類的數據從class文件載入到內存,並對數據進行 校驗/准備/解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這個過程被稱作虛擬機的類載入機制。
稱作虛擬機的類載入機制。
loading -> linking (verification -> preparation -> resolution)-> resolution)->initializing
loading: 把class文件load到內存中,採用雙親委派,主要是為了安全性
verification: 校驗class文件是否符合標准
preparation: 靜態變數分配內存並設初始值的階段(不包括實例變數)
resolution:把符號引用轉換為直接引用
initializing:靜態變數賦初始值
類載入的過程主要分為三個部分:載入、連接、初始化這三個階段。
類的載入指的是將類的.class文件中的二進制數據讀入到內存中,將其放在運行時數據區的方法區內,然後在堆區創建一個這個類的java.lang.Class對象,用來封裝類在方法區類的對象。主要步驟可以分為下面的三件事情:
載入階段完成後,虛擬機外部的 二進制位元組流就按照虛擬機所需的格式存儲在方法區之中,而且在Java堆中也創建一個java.lang.Class類的對象,這樣便可以通過該對象訪問方法區中的這些數據。
類的載入的最終產品是位於堆區中的Class對象。Class對象封裝了類在方法區內的數據結構,並且向Java程序員提供了訪問方法區內的數據結構的介面。載入類的方式有以下幾種:
2.載入器
JVM的類載入是通過ClassLoader及其子類來完成的,類的層次關系和載入順序可以由下圖來描述:
1.BootstrapClassLoader(啟動類載入器)
在連接裡面又可以被分成3個小階段,分別是:驗證,准備,解析
1.驗證(目的):
2.驗證內容:
驗證是連接階段的第一步,這一階段的目的是為了確保Class文件的位元組流中包含的信息符合當前虛擬機的要求,並且不會危害虛擬機自身的安全。驗證階段大致會完成4個階段的檢驗動作:
驗證階段是非常重要的,但不是必須的,它對程序運行期沒有影響,如果所引用的類經過反復驗證,那麼可以考慮採用-Xverifynone參數來關閉大部分的類驗證措施,以縮短虛擬機類載入的時間。
3.准備:
在准備階段,為靜態變數的初值為jvm默認的初值,而不是我們在程序中設定的初值。jvm默認為靜態變數的初值是這樣的
4.解析:
這一階段的任務就是把常量池中的符號引用轉換為直接引用 什麼是符號引用,什麼是直接引用。
1.工作內容:
JVM負責主要對類變數(類變數就是static修改的變數)進行初始化這里主要對類變數(類變數就是static修改的變數)進行初始化,初始化主要有兩個方式:
2.初始化時機:
類初始化時機:只有當對類的主動使用的時候才會導致類的初始化,類的主動使用包括以下六種:
3.初始化順序:
如果有父類,則順序是:父類static方法/static變數賦值 –> 子類static方法/static變數賦值
三、結語:
上面介紹的就是類(class)的載入,包含它的載入、鏈接、初始化。
Android進階知識點,我最近整理了許多,裡面講解的非常詳細。取
https://docs.qq.com/doc/DUkNRVFFzTG96VHNiAndroid 技術進階手冊丶面試題綱丶核心筆記資料。