在java中,static作为静态修饰符用来修饰成员变量和成员方法。
被static修饰的成员变量或成员方法,独立于该类的任何对象,也就是说他不依赖于该类的实例,同时也可以被所以实例所共享。
静态成员在类第一次被加载的时候就会被虚拟机加载到方法区中。
因此静态成员可以直接通过类名调用来访问。
类名.静态方法名(参数列表...);
类名.静态变量名;
一、static的用途
1、静态方法
静态方法可以不依赖任何实例访问,可直接通过类名调用。
因此,静态方法中不存在this和super关键字。
而且由于这个特性,静态方法中不可以访问非静态的变量或者非静态的方法。
因为非静态成员只能通过类的实例化调用,静态的加载优先于类的实例化。
尽管静态方法中不可以访问非静态成员,但是非静态方法中是可以访问到静态成员的。
2、静态变量
静态变量和非静态变量的区别:
静态变量存在于方法区中,在类初次被加载时初始化。它被所有对象所共享,在内存中只有一个,一般通过类名访问。
非静态变量存在于对象中,在创建对象时被初始化。每次创建对象时都会分配一次内存,在内存中可以有多个副本,且互不影响,一般通过对象名访问。
3、静态代码块
静态代码块是独立于类中成员的代码块。静态代码块可以再类中的任何位置,类中可以有多个静态代码块。
静态代码块在类不初次加载的时候从上到下按顺序加载,且只执行一次。
静态代码块常用于类属性的初始化,可以优化程序性能。
二、实例题目
public class Test {
Person person = new Person("Test");
static{
System.out.println("test static");
}
public Test() {
System.out.println("test constructor");
}
public static void main(String[] args) {
new MyClass();
}
}
class Person{
static{
System.out.println("person static");
}
public Person(String str) {
System.out.println("person "+str);
}
}
class MyClass extends Test {
Person person = new Person("MyClass");
static{
System.out.println("myclass static");
}
public MyClass() {
System.out.println("myclass constructor");
}
}
运行结果:
test static
myclass static
person static
person Test
test constructor
person MyClass
myclass constructor
1、主函数在Test类中,所以先加载Test类,在加载Test类时会执行Test类的静态代码块。打印test static。
2、在主函数中new了个MyClass类对象,执行MyClass类时发现MyClass类继承自Test类,但Test类已经被加载了,所以加载MyClass类,并执行了静态代码块。打印myclass static。
3、在通过MyClass类的构造方法生成变量的时候首先会初始化父类的成员变量,因此会new一个Person类对象,而Persom类还没有被加载,所以加载Person类,并执行静态代码块。打印person static。
4、然后执行Person类的构造方法。打印person Test。
5、初始化父类变量之后执行父类的构造方法(继承的子类的构造方法中默认存在super();),打印test constructor。
6、完成父类的初始化之后,初始化自身,先对自身的成员变量初始化。打印person MyClass。
7、最后执行自身的构造方法。打印myclass constructor。