static 从字面上讲就是“静态”的意思,可以用来修饰类、类的成员变量、类的方法,同时也可以通过使用static来形成静态代码块。
被static修饰的类的成员变量和成员方法独立于该类的任何实例对象,也就是说它不依赖类特定的实例,被类的所有实例所共享。
当类的成员变量前面用public static修饰时,表示成员变量(方法)在本质上时全局变量(方法),当声明该类的实例时,不生成public static修饰的变量(方法)的副本,而是类的所有对象共用一个static 变量(方法)
当类的成员变量前面用private static修饰时,与采用public static修饰的主要区别就是被修饰的变量或方法不能再其他类中通过类名来直接进行访问,由此可以看出区别就在与访问权限关键字public同private的区别,其他的访问权限关键字一次类推。
1、静态变量与实例变量
static修饰的变量就是静态变量(类变量),没被static修饰的变量就是实例变量。二者的区别在于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态变量分配一次内存(该分配发生在加载类的过程中),可以通过类名直接访问,也可以通过类的实例对象来访问(不推荐);实例变量每创建一个实例,都会在内存中单独分配一次内存,实例变量可以在内存中存在多个拷贝,且这多个拷贝相互之间互不影响。
所以一般在实现以下两个功能时会用到静态变量
- 在类的对象之间共享值时;
- 需要便捷访问某个变量时;
public class StaticTest {
private static int a;
private int b;
// static代码块1
static {
StaticTest.a = 3;
System.out.println(a);
StaticTest t = new StaticTest();
// 调用成员变量和成员方法
t.f();
t.b = 1000;
System.out.println(t.b);
}
public static void main(String[] args) {
System.out.println("Hello World!");
}
// static代码块2
static {
StaticTest.a = 5;
System.out.println(a);
}
public void f(){
System.out.println("Static test!");
}
}
输出结果:
3Static test!10005Hello World!
- 对于变量,表示一旦赋值就不可修改,并且可以通过类名进行访问;
- 对于方法,表示该方法不可覆盖,并且可以通过类名进行访问;
小结以下
- static修饰成员变量JVM只为其分配一次内存,这次内存分配发生在该static成员所在类加载时;
- static方法中不能直接使用非静态成员和方法,能调用静态方法,可访问静态成员变量;
- static方法独立于类具体对象存在,所以在static方法体内不能存在类对象相关的关键字(如this和super);