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为何具备这些特性,望同行能在评论区点拨指正。
相关文章
相关标签/搜索