大前提static静态资源只会加载一次,并放在方法区对应的类的静态区
因为这个特性,static经常用来做优化程序性能
1.类加载
说到static就不能不提类加载,在Java中类加载是,在你使用到哪个类时,哪个类才会加载,就如同你在玩游戏时加载资源一样,都玩过英雄联盟或者王者荣耀吧,双方十个人在进入对局的时候会有加载界面,加载的就是这个对局的资源,地图,人物模型,皮肤,特效等,好比你们十个人中并没有瑞雯,这时加载就不会把瑞雯的模型,皮肤,技能特效加载进来,这样做的好处就是资源不会浪费。类加载同理,JVM 会根据当前程序运行所需,加载所有的所需的类文件(.class 文件),程序准备阶段,并且在准备阶段过程中,会执行加载static修饰相关内容(包括static修饰的变量,方法)。
☆2.static三个重点,一个原则
三个重点:静态成员变量,静态成员方法,静态代码块
一个原则:类加载过程中,static完成准备工作
2.1static修饰静态成员变量
static 修饰的静态成员变量在整个代码的运行周期中有且只有一个!静态成员变量在内存的【数据区】
static 修饰的静态成员变量在类文件加载阶段,需要准备就绪,已具备数据提供能力和数据存储能力
static 修饰的静态成员变量别名【类变量】,语法建议直接通过类名操作,例如Arrays.toString()
static 修饰的静态成员变量的生命周期是从类加载开始到程序终止结束,因此静态成员变量最好不要和类对象有相关性,类对象的生命周期从实例化对象开始,到JVM的GC回收结束
2.2static修饰静态成员方法
static 修饰的静态成员方法不允许使用类内的【非静态成员】
static 修饰的静态成员方法在类文件加载阶段已具备执行能力,方法内有非静态相关内容,无法执行,因为非静态成员需要实例化对象调用操作,加载过程中没有相关的对象存在
static 修饰的静态成员方法可以直接使用类内的其他静态资源
2.3static修饰静态代码块
代码块有三种形式
构造代码块 { } 默认在所有构造方法执行时,在构造方法的内部第一行之前插入构造代码块的内容
局部代码块,在方法中的代码块,控制代码块内语句的生命周期
静态代码块 static { }
静态代码块在类文件加载阶段一定执行!!!并且有且只执行一次
静态代码块可以调用类内的其他静态资源
静态代码块不可以调用类内的【非静态资源】
静态代码块一般用于程序初始化操作,预处理操作,项目运行前准备工作
static面试题
读下面一端代码运行结果是什么?
public class Demo01 {
static Demo01 d1 = new Demo01();
static Demo01 d2 = new Demo01();
{
System.out.println("构造代码块");
}
static {
System.out.println("静态代码块");
}
public Demo01() {
System.out.println("构造方法");
}
public static void main(String[] args) {
Demo01 demo = new Demo01();
}
}
答案是
构造代码块
构造方法
构造代码块
构造方法
静态代码块
构造代码块
构造方法
分析:从main方法的第一句开始,需要new一个Demo01的对象,这时JVM就开始加载Demo01类,进入Demo01首先运行static修饰的代码(static修饰的不管是方法还是变量都是平级的,从上到下执行),运行第一句static Demo01 d1 = new Demo01();这次会去执行Demo01中的构造方法生成对象,构造方法在执行时会先检查是否有构造代码块,并首先执行构造代码块中的内容,之后执行构造方法的方法体,之后将这个对象传回给d1。然后加载类的第二行new一个d2出来,同new d1一样,之后再执行静态代码块中的内容,到此Demo01类加载完毕,开始给main造对象,执行构造代码块和构造方法。
ps:static只执行一次!!!
如有不足,私信或者评论指正,肥肠感激。🙋