1. 程式人生 > >java中init()和clinit()方法的區別

java中init()和clinit()方法的區別

<clinit>:在jvm第一次載入class檔案時呼叫,包括靜態變數初始化語句和靜態塊的執行

<init>:在例項創建出來的時候呼叫,包括呼叫new操作符;呼叫Class或java.lang.reflect.Constructor物件的newInstance()方法;呼叫任何現有物件的clone()方法;通過java.io.ObjectInputStream類的getObject()方法反序列化。


(1)<clinit>()方法是由編譯器自動收集類中的所有類變數的賦值動作和靜態語句塊(static)中的語句合併產生的,編譯器收集的順序是由語句在原始檔中出現的順序所決定的,靜態語句塊只能訪問到定義在靜態語句塊之前的變數,點貴在他之後的變數,在前面的靜態語句塊中可以賦值但不能訪問。

public class Test{

static{

i = 0;                                        //給變數賦值可以正常通過

System.out.println(i);               //這句編譯器會提示“非法向前引用”

}

static int i = 1;

}

(2)<clinit>()方法與類的建構函式(或者說例項構造器中的<init>()方法)不同, 它不需要顯示的呼叫父類構造器,虛擬機器會保證在子類的<init>()方法執行之前,父類的<clinit>()方法已經執行完畢。因為在虛擬機器中第一個被執行的<clinit>()方法的類肯定是java.lang.Object。

(3)由於父類的<clinit>()方法先執行,也就意味著父類中定義的靜態語句塊要優先於子類類的變數賦值操作。

(4)<clinit>()方法對於類或者介面來說並不是必須的,如果一個類沒有靜態語句塊,也就沒有變數的賦值操作,那麼編譯器可以不為這個類生成<clinit>()方法。

(5)介面中不能使用靜態語句塊,但仍然可以有變數初始化的賦值操作,因此介面與類一樣都會生成<clinit>()方法。但介面與類不同,執行介面的<clinit>()方法不需要先執行父介面的<clinit>()方法。只有當父介面中定義的變數使用時,父接口才會初始化。另外,介面的實現類在初始化時也一樣不會執行介面的<clinit>()方法。

(6)虛擬機器會保證一個類的<clinit>()方法在多執行緒環境中被正確地加鎖、同步,如果多個執行緒同時去初始化一個類,那麼只有一個執行緒去執行這個類的<clinit>()方法中有耗時很長的操作,就可能造成多個執行緒阻塞。 

相關推薦

javainit()clinit()方法區別

<clinit>:在jvm第一次載入class檔案時呼叫,包括靜態變數初始化語句和靜態塊的執行 <init>:在例項創建出來的時候呼叫,包括呼叫new操作符;呼叫Class

Javainitclinit區別完全解析

init和clinit區別 ①init和clinit方法執行時機不同 init是物件構造器方法,也就是說在程式執行 new 一個物件呼叫該物件類的 constructor 方法時才會執行init方法,而clinit是類構造器方法,也就是在jvm進行類載入—–驗證—-解析—

Javawaitsleep方法區別

lee join 告訴 inter art 過程 lam 兩個 一次 1、兩者的區別 這兩個方法來自不同的類分別是Thread和Object 最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法(鎖代碼塊和方法鎖)。 w

java sendredirect()forward()方法區別

rect 次數 報錯 nec 重定向 web服務 單獨 exception aca 一.文章1 HttpServletResponse.sendRedirect與RequestDispatcher.forward方法都可以實現獲取相應URL資源。 sendRedirect

Java OverloadOverride的區別。Overloaded的方法是否可以改變返回值的型別?

Overload是過載的意思,Override是覆蓋的意思,也就是重寫。 過載Overload表示同一個類中可以有多個名稱相同的方法,但這些方法的引數列表各不相同(即引數個數或型別不同)。 重寫Override表示子類中的方法可以與父類中的某個方法的名稱和引數完全相同,通

Java關於==equal的區別以及equals()方法重寫

例子i: string1="aaa"; string2="aaa"; String string3=new String("aaa"); String string4=new String("aaa"); string1==string2 // true; . string1.equals(string2)

java棧的區別

mem 線程 所有 生成 werror 空間 調用 訪問 指向 01,各司其職;         棧內存用來存儲局部變量和方法的調用,         而堆內存用來存儲java中的對象,無論是成員變量,局部變量,還是類變量         他們指向的對象都存儲在堆內存中。

javaComparator Comparable的區別

true public arr ins ride err instance ural code 1、Comparable的代碼如下: public interface Comparable<T> { public int compareTo(T o);

JAVA ListArrayList的區別

屬性和方法 vector 實現類 多個 一個 什麽 性能 {} 等等 List是一個接口,而ListArray是一個類。 ListArray繼承並實現了List。 所以List不能被構造,但可以向上面那樣為List創建一個引用,而ListArray就可以被構造。 Li

JavaRuntimeExceptionException的區別

字符 所有 數組越界 技術 ace stat ast == erro 在java的異常類體系中,Error和RuntimeException是非檢查型異常,其他的都是檢查型異常。 所有方法都可以在不聲明throws的情況下拋出RuntimeException及其子類 不可以

Java堆的區別

分配內存 基本 變量 類型 名稱 垃圾回收器 函數 一個數 棧內存 在函數中定義的一些基本類型的變量和對象的引用變量都在函數的棧內存中分配。當在一段代碼塊定義一個變量時,Java就在棧中為這個變量分配內存空間,當超過變量的作用域後,Java會自動釋放掉為該變量

Javaequalshashcode的區別

equals方法 div true 區別 hash pos post 兩個 不一定 Java中equals和hashcode方法是在Object對象中的,所以每個對象都有這兩個方法,大多數時候我們為了實現特定需求需要重寫這兩個方法 equals和hashcode方法常用在同

javaerrorexception的區別

方法調用 IE tex 錯誤 top throws detail java err 轉載 :https://blog.csdn.net/lifengguo_njupt/article/details/7990485 java中error和exception的區別 Err

javawaitsleep的區別(多線程編程)

釋放 catch 時間 編程 cpu 程序 all CA exception sleep是thread中的一個方法,wait是object中的方法。 sleep是讓一個線程進入休眠狀態,在等待一段時間之後,進入可運行狀態,等待cpu分配資源並運行。同時sleep的過程中,有

JAVAStackHeap的區別

edit sys 靈活 double 對象 情況 編譯器 特殊 建議 轉自https://blog.csdn.net/wl_ldy/article/details/5935528 1.Java中對象都是分配在heap(堆)中。從heap中分配內存所消耗的時間

JAVAimplementextends的區別

extends是繼承父類,只要那個類不是宣告為final或者那個類定義為abstract的就能繼承,Java中不支援多重繼承,但是可以用介面來實現,這樣就要用到implements,繼承只能繼承一個類,但implements可以實現多個介面,用逗號分開就行了比如class A extends B i

java 多執行緒學習(JavaThread Runnable的區別

今天剛學習java多執行緒 在網上查了幾篇博文學習,個人覺得寫的不錯,但是有的地方有個疑問:Java中Thread 和 Runnable的區別。 然後,在網上查詢相關資料,發現幾乎都是一樣的。 下面貼出相關的程式碼: 如果一個類繼承Thread,則不適合資源共享。但是如果實現了

Java newnewInstance的區別

轉載來源:https://blog.csdn.net/iloveyin/article/details/7965183 ( @iloveyin )   1、類的載入方式不同    使用關鍵字 new 建立一個類的時候,這個類可以

Javathrowsthrow的區別講解

當然,你需要明白異常在Java中式以一個物件來看待。 並且所有系統定義的編譯和執行異常都可以由系統自動丟擲,稱為標準異常,但是一般情況下Java 強烈地要求應用程式進行完整的異常處理,給使用者友好的提示,或者修正後使程式繼續執行。 直接進入正題哈: 1.使用者程式自定義的異常和應用程式特定的異常,必

javaIntegerint的區別(轉)

prev 指針 引用 .com 地址 區別 val details sdn int和Integer的區別 1、Integer是int的包裝類,int則是java的一種基本數據類型 2、Integer變量必須實例化後才能使用,而int變量不需要 3、Integer實際是對象