MO_or的Java static複習總結

1、引言

本篇文章主要借static修飾符,進一步的理解static與jvm之間聯繫。

2、總結

1. 基本概念java

靜態變量:聲明獨立於對象的靜態變量,不管一個類實例化多少對象,靜態變量只有一份拷貝,局部變量不能被聲明。
靜態方法:聲明獨立於對象的靜態方法,靜態方法不能使用類的非靜態變量。

2. 做用jvm

方便在沒有建立對象的狀況下調用方法或變量。

3. 深層原理ide

爲了解決上面的特性,首先咱們須要從jvm內存講起,
先放一張java內存結構圖,咱們再經過案例分析static修飾的變量放在哪兒。

Java runtimedate.png

從上圖能夠看出,靜態變量存放在方法區中,被全部線程共享的。
而堆中是存放實例對象的,這裏簡單的描述下堆、棧、方法區。

堆區:
1)存儲的所有是對象,每一個對象包含一個對應的class,用於接收操做指令。
2)jvm只有一個堆區(heap),並被全部線程共享,堆中不存放基本類型和對象應用,只存放實例化對象。

棧區:
1)棧分爲三個部分:基本類型變量區、執行上下文、操做指令區。
2)每一個線程包含一個獨自的棧,棧中存放的爲基本數據類型的對象與堆中實例對象的引用(地址指向堆中的實例對象)。
3)棧中的數據都是私有的,其餘棧不能訪問。

方法區:
1)也叫靜態區,和堆區同樣被全部線程共享,方法區中存放的爲class和static變量。
2)所存放的數據在整個程序中都是惟一存在的。

簡單描述了棧、堆、方法區後,咱們再結合案例從內存角度去分析,static的特性是從何而來的。
public class OnePiece {

    private static String captain;
    private String mate;

    public void showSeaman(){
        System.out.println(captain + "和" + mate);
    }
    
    /**
    * 靜態方法不能調用非靜態變量
    */
    public static void viewSeanman() {
        System.out.println(captain);
        // System.out.println(mate);
    }

    public static void main(String[] args) {
        OnePiece straw = new OnePiece();
        OnePiece.captain = "路飛";
        straw.mate = "索隆";
        straw.showSeaman();

        OnePiece redhair = new OnePiece();
        // OnePiece.captain = "香克斯";
        // redhair.mate = "本·貝克曼";
        redhair.showSeaman();
    }
}

/**
 * 輸出:
 *      路飛和索隆
 *      路飛和null
 */
接下來咱們再從內存的角度看看。

static內存.png

從上面能夠看到當咱們調用方法時,由於實例對象在堆中,因此隨着對象的銷燬,成員變量也就消失了。
但因爲靜態變量是存在方法區中的,被全部線程共享,並不會隨對象銷燬而消失。這就解釋了static所具備的特性。

3、參考

https://baijiahao.baidu.com/s?id=1636927461989417537&wfr=spider&for=pcspa

4、最後

受限於MO_or淺薄的知識體系,並無很好的闡明static爲何具備這些特性,望同行能在評論區點撥指正。
相關文章
相關標籤/搜索