在 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都是在类初始化时就进行的,变量都是在域之前进行初始化的。