Java关键字 - static
概念
在Java中,我们可以通过用static
来表示某个字段或者方法为“全局“或者”静态“的意思,当然static
也可以修饰代码块。
怎么使用static
static
可以用于修饰成员变量和成员方法,我们将其称为静态变量和静态方法,可以直接通过类名进行访问。如下所示:
- ClassName.propertyName
- ClassName.methodName()
而static
修饰的代码块也称之为静态代码块,当其所属的类被加载时,就会优先先执行这部分代码。
static变量
static
修饰的变量称之为静态变量,而没有static
修饰的变量称之为实例变量。两者的区别在于:
静态变量是随着类加载时被完成初始化的,它在内存中仅有一个,且JVM也只会为它分配一次内存,同时类所有的实例都共享静态变量,可以直接通过类名来访问。
但是实例变量则不同,他是伴随着实例的创建而创建,也伴随着实例的消亡而消亡。而且实例变量只能够通过对象进行访问。
static函数
static
修饰的方法称之为静态方法,可以直接通过类名对其进行调用。正因为static
修饰的函数在类加载的时候就已经存在了,它不依赖于任何实例,所以static
方法必须被实现,也就是说它不能够同时与abstract
搭配修饰函数。
static
方法是类中的一种特殊方法,当我们需要这个类下的某个方法完成某个特定的目的而无须将其实例化时,才将这个方法修饰为static
。如Math类下的所有方法都是静态static
的。
static代码块
static
修饰的代码块称之为静态代码块,它会随着类加载的时候一块执行。静态代码块可以放置类中任意地方,且在类加载时,静态代码块按从下到上的顺序依次执行。
使用注意
static
修饰的方法不能够调用非static
变量或者非static
方法
static
所修饰的方法是从属于类的,且被由该类实例化出的所有对象所共享。若在static
方法中调用了非static
变量或非static
方法,那么在运行期间,程序则无法确定此时的所调用的非static
变量的确切值(因为成员变量的实际值取决于其所属的对象),从而导致程序运行错误。
静态代码块与非静态代码块的初始化顺序
优先级结论:静态代码块 == 静态变量初始化 > 实例代码块 == 实例变量初始化 > 实例构造器。
1 | package util_test; |
正确的执行顺序如下所示:
1 | main static block |
分析上述的代码加载过程。
- 因为
main
方法在Main类中,所以首先加载Main类,因此会执行Main类中的static
代码块。接着执行main
方法中的new Son()
语句,而此时Son类尚未被加载,因此此时需要加载Son类。在加载Son类的时候,发现Son类是继承自Father类,所以转而去优先加载Father类,所以Father类中的static
代码块会被执行,然后再执行Son类中的static代码
块。 - 在所有所需的类加载完毕后,就通过构造器来生成对象。而在生成对象的时候,必须先初始化父类的成员变量以及执行实例代码块。因此先执行Father类中的实例代码块与构造器,最后再执行Son类中实例代码块与构造器。
参考资料