static关键字的使用
静态变量
- Java中提供了static关键字,用它来修饰类的属性后,则此属性就是公共属性了。
- 在程序中如果使用static声明变量的话,则此变量称为静态变量,也称为类变量,其作用域与该类的生存范围相同。
访问类变量的方法:
-
只要类存在,程序就可以通过该类来访问类变量:
类名.类变量
-
也可以通过该类的实例来访问类变量:
实例.类变量
由于这个实例并不拥有这个类变量,因此访问它的时候并不是访问这个实例的变量,而是访问它对应的类的类变量。因此,通过实例修改类变量的值,与通过该类修改类变量的值结果相同。如果该类有多个实例,其中一个实例修改了类变量,那么其它实例访问这个类变量时获得的值将是修改过后的值。
静态方法
- static既可以声明变量,也可以用来声明方法,用它声明的方法称为静态方法,也称为类方法。
- 注意:如果在类中声明了static类型的属性,则此属性既可以在非static类型的方法中使用,也可以在static类型的方法中使用。但用static类型的方法调用非static类型的属性时,则会出现错误(即静态成员不能访问非静态成员)。
静态代码块
一个类可以使用不包含在任何方法体中的静态代码块,当类被载入时,静态代码块被执行,且只执行一次,静态代码块经常用来进行类属性的初始化。
具体例子:
运行结果:
结果分析:
放在Test类中的静态代码块会先被调用,因为Test类为启动类,程序会首先执行启动类;
接着执行main方法,因为这是程序的入口;
而后程序创建了两个Person类的对象,但Person类中的静态代码块只会执行一次,并且静态代码块是首先被执行的;
最后Person类的无参构造方法被调用。
初始化块
- 初始化块是Java的类成员之一(其它的有成员变量、成员方法、构造器),用于对Java对象进行初始化操作,使用初始化块初始化所有对象共有的属性和方法;
- 初始化块没有名字、没有标识,无法通过类或对象来调用;
- 初始化块是构造器的补充,其总是在构造器执行之前执行。一个类里可以有多个初始化块,相同类型的初始化块之间执行有顺序:先定义的先执行,后定义的后执行;
- 初始化块不能接收任何参数;
- 初始化块分为非静态初始化块和静态初始化块。静态初始化块是对类而言,非静态初始化块是对对象而言,静态初始化块的执行顺序在非静态初始化块之前。
非静态初始化块
在每个对象生成时都会被执行一次,可以初始化类的实例变量;
与构造器类似的,创建Java对象时,总是先执行该对象所对应类的父类的非静态初始化块和构造器,执行顺序如下:先执行java.lang.Object类的非静态初始化块,执行java.lang.Object类的构造器 ——> 再执行其父类的非静态初始化块,执行其父类的构造器 ——> 最后执行该类的非静态初始化块,执行该类的构造器 ——> 返回该类的对象。
非静态初始化块语法格式:
具体例子:
运行结果:
静态初始化块
- 静态代码块在类加载时被执行;
- 与非静态初始化块类似的,执行某个类的静态代码块时,总是先从其父类开始,执行顺序如下:
先执行java.lang.Object类的静态初始化块(如果有) ——> 再执行其父类的静态初始化块(如果有) ——> 最后执行该类的静态初始化块;
- 若在静态初始化块中想初始化变量,那只能初始化类变量,即static修饰的成员变量(即遵循静态成员不能访问非静态成员的规则);
- 静态初始化只在类加载时执行一次,此后不再执行。
静态初始化块语法格式:
具体例子:
运行结果:
结果分析:
第一次创建一个Son对象时,因为系统还不存在Son类,因此需要先加载并初始化Son类,初始化Son类时会先执行其顶层父类的静态初始化块(如果有),再执行其直接父类的静态初始化块(如果有),最后才执行Son本身的静态初始化块;之后在执行非静态初始化块和构造器;
一旦Son类初始化成功后,Son类在该虚拟机一直存在,因此当第二次创建Son实例时,无须再次对Son类初始化。
final关键字的使用
- final可以用来声明类、属性、方法;
- final修饰的类不能被继承;
- fianal修饰的方法不能被子类重写;
- final修饰的变量(成员变量、局部变量)即为常量,只能赋值一次,并且只能由程序员显式地指定初始值。