搞明白了java中的static关键字以及有static时初始化阶段的顺序

本文详细解析了Java中静态变量、静态方法的概念及其使用场景,并通过具体代码示例展示了类初始化过程,包括静态变量、静态代码块及普通变量的初始化顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在 java中被static修饰的变量,方法或者域成为静态变量,静态方法或者静态域。所有被static修饰的都是属于类级别的,类中只有一份,这个类的中所有实例都将共享这个域。

静态变量可以直接通过类名来调用,不需要先实例化这个类的一个对象。在初始化时,静态域只能对静态变量进行操作,没有被static修饰的变量无法再静态域内进行操作。如果写了,编译是不通过的。

下面来举个例子

package com.test.Static;

public class Employee {

	private static int nextId=1;
	private String name;
	private double salary;
	private int id=1;
	
	{
		System.out.println("name:"+name);
		System.out.println("salary:"+salary);
		System.out.println("id:"+id);
		System.out.println("现在进行块初始化----------------");
		name="jialingLi";
		nextId=4;
		System.out.println("name:"+name);
		System.out.println("nextId:"+nextId);
		
	}
	
	static {
		System.out.println("在静态块初始化前面 静态变量 nextId"+nextId);
		System.out.println("现在进行静态块初始化");
		nextId=2;
		System.out.println("在静态块初始化时 静态变量 nextId"+nextId);
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getSalary() {
		return salary;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public Employee(String name, double salary) {
		this.name = name;
		this.salary = salary;
		id=0;
	}
	
	
	public Employee() {
		// TODO Auto-generated constructor stub
	}
	public void setId() {
		id=nextId;
		nextId++;
	}
	
	public static int getNextId() {
		return nextId;
	}
	
	
	public static void main(String[] args) {
		System.out.println("-------------------");
		Employee ee=new Employee();
		System.out.println("-------------------");
		Employee ee1=new Employee();
	}
}

结果是

在静态块初始化前面 静态变量 nextId1
现在进行静态块初始化
在静态块初始化时 静态变量 nextId2
-------------------
name:null
salary:0.0
id:1
现在进行块初始化----------------
name:jialingLi
nextId:4
-------------------
name:null
salary:0.0
id:1
现在进行块初始化----------------
name:jialingLi
nextId:4

在main函数中new了两个Employee对象,但是静态变量以及静态域就运行了一次,而普通变量和初始化块都进行了两次,在普通初始化中是可以调用静态变量的。从这也可以看出,建立对象是要先进行类初始化,顺序是:静态变量->静态代码块,然后建立对象,普通变量->普通代码块。


在加上继承这个关系试试,假设Employee继承Person类,

package com.test.Static;

public class Person {

	
	private static int sex=33;
	
	
	private String sre="大家好";
	static {
		System.out.println("person 静态代码块初始化前 sex"+sex);
		System.out.println("person 静态代码块初始化之前————————————————");
		sex=1;
		System.out.println("person 静态代码块初始化后 sex"+sex);
	}
	
	{
		System.out.println("父类块起不起作用"+sre);
		sre="你好";
		System.out.println("父类的块起作用之后"+sre);
	}
}

那么运行之后的结果是

person 静态代码块初始化前 sex33
person 静态代码块初始化之前————————————————
person 静态代码块初始化后 sex1
在静态块初始化前面 静态变量 nextId1
现在进行静态块初始化
在静态块初始化时 静态变量 nextId2
-------------------
父类块起不起作用大家好
父类的块起作用之后你好
name:null
salary:0.0
id:1
现在进行块初始化----------------
name:jialingLi
nextId:4
-------------------
父类块起不起作用大家好
父类的块起作用之后你好
name:null
salary:0.0
id:1
现在进行块初始化----------------
name:jialingLi
nextId:4

也就是说建立对象的顺序是这样的,先是初始化类,而Employee类继承了Person类,所以先是父类静态变量->父类静态域->子类静态变量->子类静态域;然后在建立对象,每个对象都有 父类普通变量->父类普通实体化域->子类普通变量->子类普通实体域。

总结就是:所有的static都是在类初始化时就进行的,变量都是在域之前进行初始化的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值