**背景:**我们系统的报表导出格式一般是文件名+yyMMdd(如数据统计20220830.xls),后面的日期是可以的根据时间改变的,但是最近生产发现了一个问题,日期不改变了,不管啥时候导出,后面的日期都是同样的。这个问题就很费解,测试环境和我们的开发环境都不能复现这个问题,潜意识里面认为这个是不可能的,因为功能上线好久了,不应该现在才发现这个问题。然后我们就排除问题,查看服务器时间是否正确啥的,最终无果,就觉得很奇怪。后来突然想起来可能是static关键字的问题。修改代码,问题得以解决。故今天就想谈一谈这个关键字。
static 可以修饰变量和方法,也有static静态代码块。被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象 其次,静态变量随着类的加载产生,随着类的消失结束(静态变量的生命周期)
父类 A
public class A {
static{
System.out.println("父类静态变量");
}
public A(){
System.out.println("父类构造方法r");
}
}
子类B
public class B extends A {
static{
System.out.println("子类静态变量");
}
public B(){
System.out.println("子类的构造方法");
}
public static void main(String[] args) {
new B();
}
}
执行结果如下:
由以上test可以稍微有点总结
JAVA类首次装入时,会对静态成员变量或方法进行一次初始化,但方法不被调用是不会执行的,静态成员变量和静态初始化块级别相同,非静态成员变量和非静态初始化块级别相同。
初始化顺序:先初始化父类的静态代码—>初始化子类的静态代码–>
(创建实例时,如果不创建实例,则后面的不执行)初始化父类的非静态代码(变量定义等)—>初始化父类构造函数—>初始化子类非静态代码(变量定义等)—>初始化子类构造函数
类只有在使用New调用创建的时候才会被JAVA类装载器装入创建类实例时,首先按照父子继承关系进行初始化类实例创建时候,首先初始化块部分先执行,然后是构造方法;然后从本类继承的子类的初始化块执行,最后是子类的构造方法类消除时候,首先消除子类部分,再消除父类部分