static关键字是静态修饰符
static 的含义
java中,jvm加载一个类,会动态的给类分配内存空间,根据变量、方法的特性决定内存空间的周期以及销毁时间等
通常static表示静态,不是动态,所以在java中,一个类在程序进行编译时分配内存时,如果类中存在 static ,那么 jvm 会给 static 修饰的内容分配一块空间,这块内存空间会随着类一直存在,并且在程序运行期间,所有类的所有实例都可以访问这块内存空间,直到类运行结束,才会释放,
static 用法
在要修饰的成员变量或方法上直接使用 static 关键字进行修饰
被static吸烟室的成员,再累中可以直接通过类名进行访问:类名.成员
static 变量
static修饰变量叫做静态变量
一般类的普通变量,也叫实例变量,jvm 在编译类时,会根据实例来产生实例变量分配内存,如果一个类中有一个实例变量,但是这个类被实例化了两次,那么这两个实例使用类中的实例变量,jvm 会产生两个实例变量的内存空间;
一个静态变量,在 jvm 开始加载类时会进行初始化,这时会加载静态变量并为这个变量分配唯一一个内存空间,在类中的所有实例都共享这一个空间,使用时通过类名.访问;因为静态变量是唯一的内存空间,所以只要类的一个实例修改这个变量,那么以后其他实例访问这个静态变量,结果都是之前修改过的结果
1 | public class ChinaPerson{ |
运行结果:
1 | 张三 是China人 |
在以上程序中,nation 变量被 static 修饰,所以程序在编译时 jvm 会给 nation 变量分配一个内存空间 ChinaPerson 的所有的实例都共享这个变量的空间;cp2 在访问过 nation 变量后,修改值为“英国”,在之后 cp3 和 cp4 再进行访问 nation 时,还是同样的一个空间,但是值已经被修改,所以这两个实例拿到的变量值是“英国”
static 方法
static 修饰的方法,通过类名.调用,
每一个类的实例都可以进行共享调用,不针对某个实例,所以静态方法中不能使用关键字this、super等;记住:this指得是对象,随着对象的创建而创建;static是随着类加载二加载,是唯一的
静态方法只能访问类的静态成员变量和静态成员方法;但是非静态方法能访问所有静态非静态的变量和方法
比如,类的 main 方法,就不能直接通过类名访问静态的成员变量,因为 main() 是 static 的
static 代码块
被static 修饰的一段{}包括起来的代码块,再类中独立存在,不能放在方法体内
jvm加载类的时候回首先加载执行这些独立的代码块,如果类中存在多个静态代码块,那么会按照代码块存在类中的先后顺序进行加载
static 代码块和 static 方法的区别
- static 代码块
- 代码块在 jvm 加载类时便会初始化并且执行代码块语句
- static 方法
- 方法时在 jvm 加载类时初始化加载,但是不执行,只有在被调用时才会执行语句;
- 调用不需要类实例化对象,可以直接使用类名进行调用
static 变量和普通成员变量
- static 变量
- 加载:类加载时初始化并创建内存空间,在类从创建到完成过程中只有一个内存空间
- 内存:类的所有实例都会共享一个static变量空间,他属于类、
- 生命周期:静态变量的生命周期跟类相同,随着类的创建而创建,随着类的销毁而销毁
- 调用:通过类名直接调用,也可以通过类的实例对象调用
- 普通成员变量
- 加载:类加载后,类的实例化对象调用时才会创建内存空间
- 内存:有几个类的实例调用变量,变量就会有几个内存空间,普通变量是被实例私有,是属于实例对象
- 生命周期:成员变量是随着对象创建而创建,随着对象的销毁而消失
- 调用:只能通过类的实例对象调用