欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳談jvm--Java中init和clinit的區(qū)別

 更新時間:2017年10月09日 10:03:54   作者:HankingHu  
下面小編就為大家?guī)硪黄斦刯vm--Java中init和clinit的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

init和clinit區(qū)別

①init和clinit方法執(zhí)行時機不同

init是對象構(gòu)造器方法,也就是說在程序執(zhí)行 new 一個對象調(diào)用該對象類的 constructor 方法時才會執(zhí)行init方法,而clinit是類構(gòu)造器方法,也就是在jvm進行類加載—–驗證—-解析—–初始化,中的初始化階段jvm會調(diào)用clinit方法。

②init和clinit方法執(zhí)行目的不同

init is the (or one of the) constructor(s) for the instance, and non-static field initialization.
clinit are the static initialization blocks for the class, and static field initialization.

上面這兩句是Stack Overflow上的解析,很清楚init是instance實例構(gòu)造器,對非靜態(tài)變量解析初始化,而clinit是class類構(gòu)造器對靜態(tài)變量,靜態(tài)代碼塊進行初始化??纯聪旅娴倪@段程序就很清楚了。

class X {
  static Log log = LogFactory.getLog(); // <clinit>
  private int x = 1;  // <init>
  X(){
   // <init>
  }
  static {
   // <clinit>
  }
}

clinit詳解

在準備階段,變量已經(jīng)賦過一次系統(tǒng)要求的初始值,而在初始化階段,則根據(jù)程序員通過程序制定的主觀計劃去初始化類變量和其他資源,或者可以從另外一個角度來表達:初始化階段是執(zhí)行類構(gòu)造器<clinit>()方法的過程。

①<clinit>()方法是由編譯器自動收集類中的所有類變量的賦值動作和靜態(tài)語句塊(static{}塊)中的語句合并產(chǎn)生的,編譯器收集的順序是由語句在源文件中出現(xiàn)的順序所決定的,靜態(tài)語句塊中只能訪問到定義在靜態(tài)語句塊之前的變量,定義在它之后的變量,在前面的靜態(tài)語句塊可以賦值,但是不能訪問如下代碼

public class Test{
static{
i=0;//給變量賦值可以正常編譯通過
System.out.print(i);//這句編譯器會提示"非法向前引用"
}
static int i=1;
}

②虛擬機會保證在子類的<clinit>()方法執(zhí)行之前,父類的<clinit>()方法已經(jīng)執(zhí)行完畢。 因此在虛擬機中第一個被執(zhí)行的<clinit>()方法的類肯定是java.lang.Object。由于父類的<clinit>()方法先執(zhí)行,也就意味著父類中定義的靜態(tài)語句塊要優(yōu)先于子類的變量賦值操作,如下代碼中,字段B的值將會是2而不是1。

static class Parent{
  public static int A=1;
  static{
  A=2;}
  static class Sub extends Parent{
  public static int B=A;
  }
  public static void main(String[]args){
  System.out.println(Sub.B);
  }
}

③接口中不能使用靜態(tài)語句塊,但仍然有變量初始化的賦值操作,因此接口與類一樣都會生成<clinit>()方法。 但接口與類不同的是,執(zhí)行接口的<clinit>()方法不需要先執(zhí)行父接口的<clinit>()方法。 只有當父接口中定義的變量使用時,父接口才會初始化。 另外,接口的實現(xiàn)類在初始化時也一樣不會執(zhí)行接口的<clinit>()方法。

注意:接口中的屬性都是static final類型的常量,因此在準備階段就已經(jīng)初始化話。

以上這篇詳談jvm--Java中init和clinit的區(qū)別就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java @Transactional與synchronized使用的問題

    Java @Transactional與synchronized使用的問題

    這篇文章主要介紹了Java @Transactional與synchronized使用的問題,了解內(nèi)部原理是為了幫助我們做擴展,同時也是驗證了一個人的學習能力,如果你想讓自己的職業(yè)道路更上一層樓,這些底層的東西你是必須要會的
    2023-01-01
  • SpringBoot基于Mybatis-Plus自動代碼生成

    SpringBoot基于Mybatis-Plus自動代碼生成

    這篇文章主要介紹了SpringBoot基于Mybatis-Plus自動代碼生成,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • 聊聊MultipartFile與File的一些事兒

    聊聊MultipartFile與File的一些事兒

    這篇文章主要介紹了MultipartFile與File的一些事兒,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 一文徹底搞懂Java日期時間類詳解

    一文徹底搞懂Java日期時間類詳解

    這篇文章主要給大家介紹了關(guān)于Java日期時間類的相關(guān)資料,Calendar類的功能要比Date類強大很多,可以方便的進行日期的計算,獲取日期中的信息時考慮了時區(qū)等問題,需要的朋友可以參考下
    2023-10-10
  • SpringBoot中JPA更新時部分字段無效

    SpringBoot中JPA更新時部分字段無效

    本文主要介紹了SpringBoot中JPA更新時部分字段無效,在通過注解自動更新時,部分字段在調(diào)試時可以找到,卻沒有被自動更新到數(shù)據(jù)庫中,下面就介紹一下解決方法
    2023-04-04
  • 舉例解析Java的設(shè)計模式編程中里氏替換原則的意義

    舉例解析Java的設(shè)計模式編程中里氏替換原則的意義

    這篇文章主要介紹了Java的設(shè)計模式中里氏替換原則的意義,文中舉例來說明里氏替換原則中強調(diào)的繼承特性方面可能帶來的問題,需要的朋友可以參考下
    2016-02-02
  • Java壓縮文件操作詳解

    Java壓縮文件操作詳解

    這篇文章主要為大家詳細介紹了如何利用Java語言進行壓縮文件操作,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2022-08-08
  • Java利用布隆過濾器實現(xiàn)快速檢查元素是否存在

    Java利用布隆過濾器實現(xiàn)快速檢查元素是否存在

    布隆過濾器是一個很長的二進制向量和一系列隨機映射函數(shù)。布隆過濾器可以用于檢索一個元素是否在一個集合中。本文就來詳細說說實現(xiàn)的方法,需要的可以參考一下
    2022-10-10
  • java多線程關(guān)鍵字final和static詳解

    java多線程關(guān)鍵字final和static詳解

    這篇文章主要介紹了java多線程關(guān)鍵字final和static詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • Springboot基礎(chǔ)之RedisUtils工具類

    Springboot基礎(chǔ)之RedisUtils工具類

    本文來說下RedisUtils工具類,主要介紹了整合Redis、MyBatis,封裝RedisUtils工具類等知識,文中有非常詳細的代碼示例,對正在學習java的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-05-05

最新評論