javaSE学习-面向对象6-static-关键字

static关键字是静态修饰符

static 的含义

java中,jvm加载一个类,会动态的给类分配内存空间,根据变量、方法的特性决定内存空间的周期以及销毁时间等

通常static表示静态,不是动态,所以在java中,一个类在程序进行编译时分配内存时,如果类中存在 static ,那么 jvm 会给 static 修饰的内容分配一块空间,这块内存空间会随着类一直存在,并且在程序运行期间,所有类的所有实例都可以访问这块内存空间,直到类运行结束,才会释放,

static 用法

在要修饰的成员变量或方法上直接使用 static 关键字进行修饰

被static吸烟室的成员,再累中可以直接通过类名进行访问:类名.成员

static 变量

static修饰变量叫做静态变量

一般类的普通变量,也叫实例变量,jvm 在编译类时,会根据实例来产生实例变量分配内存,如果一个类中有一个实例变量,但是这个类被实例化了两次,那么这两个实例使用类中的实例变量,jvm 会产生两个实例变量的内存空间;

一个静态变量,在 jvm 开始加载类时会进行初始化,这时会加载静态变量并为这个变量分配唯一一个内存空间,在类中的所有实例都共享这一个空间,使用时通过类名.访问;因为静态变量是唯一的内存空间,所以只要类的一个实例修改这个变量,那么以后其他实例访问这个静态变量,结果都是之前修改过的结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ChinaPerson{
public String name;
public static String nation = "China";
public void personInfo(String name){
System.out.println(name+" 是"+ ChinaPerson.nation);
}
public static void main(String[] args){
ChinaPerson cp1 = new ChinaPerson();
cp1.personInfo("张三");
ChinaPerson cp2 = new ChinaPerson();
cp2.personInfo("李四");
cp2.nation = "英国";
ChinaPerson cp3 = new ChinaPerson();
cp3.personInfo("王五");
ChinaPerson cp4 = new ChinaPerson();
cp4.personInfo("孙悟空");
}
}

运行结果:

1
2
3
4
张三 是China人
李四 是China人
王五 是英国人
孙悟空 是英国人

在以上程序中,nation 变量被 static 修饰,所以程序在编译时 jvm 会给 nation 变量分配一个内存空间 ChinaPerson 的所有的实例都共享这个变量的空间;cp2 在访问过 nation 变量后,修改值为“英国”,在之后 cp3 和 cp4 再进行访问 nation 时,还是同样的一个空间,但是值已经被修改,所以这两个实例拿到的变量值是“英国”

static 方法

static 修饰的方法,通过类名.调用,

每一个类的实例都可以进行共享调用,不针对某个实例,所以静态方法中不能使用关键字this、super等;记住:this指得是对象,随着对象的创建而创建;static是随着类加载二加载,是唯一的

静态方法只能访问类的静态成员变量和静态成员方法;但是非静态方法能访问所有静态非静态的变量和方法

比如,类的 main 方法,就不能直接通过类名访问静态的成员变量,因为 main() 是 static 的

static 代码块

被static 修饰的一段{}包括起来的代码块,再类中独立存在,不能放在方法体内

jvm加载类的时候回首先加载执行这些独立的代码块,如果类中存在多个静态代码块,那么会按照代码块存在类中的先后顺序进行加载

static 代码块和 static 方法的区别

  • static 代码块
    • 代码块在 jvm 加载类时便会初始化并且执行代码块语句
  • static 方法
    • 方法时在 jvm 加载类时初始化加载,但是不执行,只有在被调用时才会执行语句;
    • 调用不需要类实例化对象,可以直接使用类名进行调用

static 变量和普通成员变量

  • static 变量
    • 加载:类加载时初始化并创建内存空间,在类从创建到完成过程中只有一个内存空间
    • 内存:类的所有实例都会共享一个static变量空间,他属于类、
    • 生命周期:静态变量的生命周期跟类相同,随着类的创建而创建,随着类的销毁而销毁
    • 调用:通过类名直接调用,也可以通过类的实例对象调用
  • 普通成员变量
    • 加载:类加载后,类的实例化对象调用时才会创建内存空间
    • 内存:有几个类的实例调用变量,变量就会有几个内存空间,普通变量是被实例私有,是属于实例对象
    • 生命周期:成员变量是随着对象创建而创建,随着对象的销毁而消失
    • 调用:只能通过类的实例对象调用