static关键字常常和final关键字一起讨论,当人们谈论final关键字时,基本都会一起讨论static关键字,但是与final关键字不同的是,static关键字修饰的成员并不是不可变的。
static关键字常用来修饰:变量、方法、类、静态代码块、静态导包
static关键字修饰成员变量:
当使用static关键字修饰成员变量时,该变量就变成了类变量,可以通过类名.变量名直接引用,而不需要new出一个对象来访问,static修饰的变量也叫做静态变量,静态变量和非静态变量的区别是:静态变量被所有对象共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。静态变量只有一个副本,所以,一处变,处处变。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
举个例子:
如果将变量定义为static,每个类中只有一个这样的变量。而每一个对象对于所有的实例域 却都有自己的一份拷贝。例如,假定需要给每一个雇员赋予唯一的标识码、这里给Employee类添加一个实例域id和一个静态域nextld:
class Employee
{
private static int nextld = 1;
private int id;
}
现在,每一个雇员对象都有一个自己的id域,但这个类的所有实例将共享一个nextld 域。换句话说,如果有1000个Employee类的对象,则有1000个实例域id。但是,只有一 个静态域nextld。即使没有一个雇员对象,静态域nextld也存在。它属于类,而不属于任何独立的对象。
从JVM的类加载机制的角度讲,静态资源是类初始化的时候加载的,而非静态资源是类new的时候加载的。类的初始化早于类的new。所以,当一个类被加载时,静态资源就已经初始化了。
static关键字修饰方法
如果一个方法被static修饰,此时这个方法就是静态方法,同样的可以通过类名.方法名来访问,而不需要new一个对象,但是需要注意的是,在静态方法中无法引用非静态资源,但是在非静态方法中却是可以引用静态资源的,还有,静态方法不能使用this关键字。
static修饰代码块
static修饰静态代码块可以说用的非常普遍,使用static修饰的代码块会在类被加载时操作并且只会被操作一次,无论这个类new了多少个对象,静态代码块执行一次,而执行的时间就是在类加载的时候,通常被用来做初始化,但是要注意的是,这个时候可以对变量做初始化,但是不可以访问。
静态资源的加载顺序是严格按照静态资源的定义顺序来加载的。static静态代码块可以置于类中的任何地方,类中可以有多个static静态代码块。在类初次被加载的时候,会按照static块的顺序来依次执行每个static块。在《深入理解Java虚拟机:JVM高级特性与最佳实践》中类初始化中的说法“<clinit>()方法是由编译器自动收集类中所有类变量的赋值动作和静态语句块(static{}块)中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序所决定的”,同样表明了,类加载时会根据静态资源的顺序来加载静态资源。静态代码块是严格按照父类静态代码块->子类静态代码块的顺序加载的,且只加载一次。
static关键字修饰类:
static一般是不会用来修饰一个类的,但是如果必须要修饰一个类,那么这个类必须为内部类,即匿名内部类。