Java中的static详解
static可以用来修饰成员变量,方法,代码块。使用static修饰的变量,方法称为静态成员。静态成员附属于类本身,而不依赖于类的实例对象。
static的基本使用方法:
/**
* static的基本用法
* @author wangcan
*
*/
public class Test {
static int num = 1;
public static void Print(){
System.out.println("static 函数调用");
}
static{
System.out.println("静态代码块");
}
public static void main(String[] args) {
System.out.println(Test.num);//直接使用类名来访问静态成员变量
Test.Print();//直接使用类名来访问静态成员函数
}
}
被static修饰的变量,在类被创建后就会一直存在,其生命周期与其所在的类相同。若一个类有多个实例对象,这些实例对象都会共用该静态成员变量。同时在类不创建实例对象的情况下,可以直接使用类名来访问。静态方法也是一样的。static代码块有助于提高程序的性能,因为它只会在类初次加载的时候进行初始化,且这个过程只会执行一次。从而避免每次创建对象都要进行初始化的static中的操作,降低了开销。
main方法为什么用static修饰
程序在执行main方法的时候没有创建任何对象,只有通过类名来访问,所以这时就需要使用static了。
static访问相关
在静态方法或静态块中是不能访问非静态的成员变量的。因为当类被Java虚拟机载入的时候,会对static变量进行初始化。而在类对象创建时才会对类中的非静态成员变量进行初始化操作。
可以看到static并不会影响成员的访问权限。(这点和C++是不同的)
关于static执行顺序的一道题
public class X {
Y y = new Y();
static {
System.out.println("tttt");
}
X() {
System.out.println("X");
}
public static void main(String[] args) {
new Z();
}
}
class Y {
Y() {
System.out.println("Y");
}
}
class Z extends X {
Y y = new Y();
static {
System.out.println("tt");
}
Z() {
System.out.println("Z");
}
}
输出结果如下:
我们来分析一下没行的输出。
1. 看一个程序自然要先从main函数开始,我们看main函数所在类为类X,首先虚拟器(JVM)会把对类X进行加载,此时则会执行类X中的static代码块,输出 tttt
2. 然后程序接着执行到main函数中创建Z对象,我们的视线转向类Z ,看到类Z继承自类X,类X是已经加载过的,我们不管他,然后会执行类Z中的静态代码块,输出 tt
3. 接下来就是实例化对象了,因为类Z继承自类X,所以先实例化类X中的对象,在类X中定义了类Y的对象(Y y = new Y() )所以先调用类Y的构造函数,输出Y
4. 然后调用类X的构造函数,输出X
5. 再构造子类Z的对象,看到在子类Z中也定义了类Y的对象,所以先调用类Y的构造函数,输出Y
6. 最后调用子类Z的构造函数,输出Z