静态修饰符(Static)
由static修饰的变量、常量和方法称为静态变量、静态常量和静态方法。
内存中的静态区在整个程序运行结束之后才会释放,所以用静态修饰的代码的生命周期是整个程序的生命周期。
静态区
内存中静态区的变量可以被本类共享,其他类调用本类静态变量和静态方法时,无需实例化就可以调用。
静态变量
很多时候,不同的类之间需要对同一个变量进行操作。
比如,一个水池,同时打开进水口和放水口,进水和出水这两个动作会同时影响池中的水量,这时,池中的水量就可以认为是一个共享的变量。
静态变量的定义和调用:
public class Pool {
static int water=0;
public void outlet(){
if(water>=2) water-=2;
}
public void inlet(){
water+=3;
}
public static void main(String[] args) {
Pool in = new Pool();
Pool out = new Pool();
System.out.println("进两次水");
in.inlet();
in.inlet();
System.out.println("还剩:"+Pool.water+"的水");
System.out.println("放两次水");
out.outlet();
out.outlet();
System.out.println("还剩:"+water+"的水");
}
}
输出结果:
进两次水
还剩:6的水
放两次水
还剩:2的水
同一个类的不同实例对象,共用同一静态变量,如果一个对象将其更改,另一个对象的静态变量也会更改。
public class StaticAge {
int x = 0;
static int y = 0;
public StaticAge(int x, int y){
this.x=x;
this.y=y;
}
public static void main(String[] args) {
StaticAge a = new StaticAge(1,2);
StaticAge b = new StaticAge(4,6);
System.out.println("a.x= "+a.x);
System.out.println("a.y= "+a.y);
System.out.println("b.x= "+b.x);
System.out.println("b.y= "+b.y);
System.out.println("y= "+y);
}
}
输出结果:
a.x= 1
a.y= 6
b.x= 4
b.y= 6
y= 6
个人理解认为是,如果一个变量是静态变量,那么不同实例对其的调用不起作用,整个程序只存在一个y
,与其所属类的实例无关。
内存中两个类的y
指向同一个位置
静态常量
用final static
修饰一个成员变量,这个成员变量就会变成一个静态常量。
定义静态常量:final static double PI = 3.1415926;
静态常量赋值后后面不能通过赋值修改。
静态方法
如果想要使用类中的成员方法,需要先将这个类进行实例化。
有时不想或者无法创建类的对象时,可以使用静态方法,使用类的静态方法无需创建类的对象。
成员方法和静态方法的使用区别:
public class StaticMethod {
public void Show(){
System.out.println("kkkkkk");
}
static public void show(){
System.out.println("23333");
}
public static void main(String[] args) {
StaticMethod Showw = new StaticMethod();
Showw.Show();
StaticMethod.show();
}
}
静态代码块
在类中的成员方法之外,用static
修饰的代码区域称之为静态代码块。
定义一块静态代码块,可以完成类的初始化操作,在类的声明时就会运行。
静态代码块、构造方法、成员方法的运行顺序:
public class StaticCode {
static{
System.out.println("StaticCodeBlock");
}
{
System.out.println("CodeBlock");
}
public StaticCode(){
System.out.println("构造方法");
}
public void method(){
System.out.println("成员方法");
}
public static void main(String[] args) {
StaticCode test = new StaticCode();
test.method();
}
}
输出:
StaticCodeBlock
CodeBlock
构造方法
成员方法
调换顺序:
public class StaticCode {
{
System.out.println("CodeBlock");
}
static{
System.out.println("StaticCodeBlock");
}
public StaticCode(){
System.out.println("构造方法");
}
public void method(){
System.out.println("成员方法");
}
public static void main(String[] args) {
StaticCode test = new StaticCode();
test.method();
}
}
输出相同。
所以运行顺序:静态代码块、非静态代码块、构造方法、成员方法。