static关键字分析
一种表示静态属性的修饰符。用于为特定区域分配单一存储空间,不考虑要创建多少对象或者说根本就不创建任何对象,再就是想在没有创建对象的情况下也去调用方法。
static关键字作用
- 用来修饰类的成员
- 修饰成员变量——
静态变量
- 修饰成员方法——
静态方法
- 修饰成员变量——
- 当类被加载时,会优先被加载
- 用来修饰代码块——
静态代码块
,先于类的构造方法之前执行且只会执行一次。用来对静态成员做初始化 - 静态修饰的成员被所有的对象共享
- 调用静态方法或对象时,可以直接通过
类名.成员方法/变量
来进行访问
能实现上述作用的原理在于:
- 代码都是在编译时 由系统分配内存
- 静态变量编译时,所分配的内存会一直存在,直到程序退出时才会被释放
- 类加载时,静态变量会被放到方法区中,被所有的对象实例共用
static关键字用法
修饰类——静态类
静态类又名
静态内部类
。该类独立存在,形式上与外部类有内外关系,实际上没有任何关联,本质是为了 隐藏自身。可不依赖外部类进行实例化,只能访问外部类的静态成员变量及成员方法。
内部类
:定义在类中的另外一个类。隐藏在外部类中且封装性更强,不允许除外部类外的其他类对其进行访问。但可以直接访问到外部类的成员。
成员内部类
:可以直接使用外部类的所有成员和方法,即时是private
修饰的。
局部内部类
:内部类定义在方法内,只能在该方法或条件的作用域才能使用,退出这作用域就无法引用。
匿名内部类
:只能使用一次,通过用来简化代码编写,还有个前提条件:必须继承一个父类或实现一个接口。
1 |
|
修饰代码块——静态代码块
静态代码块用于初始化一个类的时候做操作用的,和静态变量、静态方法一样会随着类的加载一块执行,而且可以随意摆放位置。对应类加载过程的最后一步:类初始化(执行
<clinit>
方法)。
1 |
|
若存在多个 static代码块,JVM按照他们出现的先后顺序依次执行。静态代码块只能访问定义在它之前的变量,定义在其后的是不能访问的。
修饰方法——静态方法
使用
static
修饰成员方法。通过ClassName.methodName()
直接访问,由于它在类加载时就存在了,不依赖于任何实例。
1 |
|
只能访问所属类的静态成员变量和静态方法,不能使用this、super关键字
修饰变量——静态变量
使用
static
修饰变量。通过ClassName.propertyName
直接访问静态变量。静态变量是 随着类加载时完成初始化的,在内存中仅有一份,且只分配一次内存。同时被所有的实例共享静态变量。
实例变量
:每创建一个实例,JVM就会为实例变量分配一次内存,它与创建它的实例同生共死。
1 |
|
一般在这两种情况下使用静态变量
:对象之间共享数据以及访问数据。
static关键字注意事项
- 静态方法不能被覆盖,方法覆盖是动态绑定的,静态方法时在编译时静态绑定的。
- 在静态方法、静态类中无法访问非static变量、方法
- 静态方法可以引用静态的变量或方法,由于 *静态的这些都是在类加载时就加载好,都是可以互相调用到的。
- 非静态方法中也可以引用静态的变量或方法。
static关键字使用实例
单例模式
1 |
|
为何可以保证线程安全?
虚拟机可以保证一个类的类构造器
()`在多线程环境中被正确的加锁、同步。如果多个线程同时去初始化一个类,只有一个线程可以去执行类构造方法,其他线程都会阻塞等待,直到构造方法执行完毕。同一个类加载器下,一个类型只会被初始化一次。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!