内容来自《java 编程思想》。
1、static 关键字
“static 方法就是没有 this 的方法。在 static 方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用 static 方法。这实际上正是 static 方法的主要用途”。static 关键字的基本作用,一句话来描述就是:方便在没有创建对象的情况下来进行调用(方法/变量)。
(1) static 方法
static 方法称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有 this 的。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。但是在非静态成员方法中是可以访问静态成员方法/变量的。因此,如果说想在不创建对象的情况下调用某个方法,就可以将这个方法设置为 static。我们最常见的 static 方法就是 main 方法,因为程序在执行 main 方法的时候没有创建任何对象,因此只有通过类名来访问。比如:
public class Test {
public void f(){
}
public static void g(){
}
public static void main(String[] args) {
Test t = new Test();
t.f();// 通过对象调用非静态方法
g();// 静态方法直接调用
}
}
(2) static 变量
static 变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象共享,在内存中只有一个副本,它当且仅当在类初次被加载时会被初始化,并且只会被初始化一次(但是可以重新赋值)。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。static 成员变量的初始化顺序按照定义的顺序进行初始化。
(3) static 代码块(静态代码块)
static 关键字还有一个比较关键的作用就是用来形成静态代码块以优化程序性能,主要用来初始化。静态代码块可以置于类中的任何地方,类中可以有多个 static 块。在类初次被加载的时候,会按照 static 块的顺序来执行每个 static 块,并且只会执行一次。
2、final关键字
final 的意思就是不可更改的意思,指的是无法改变的量。这与静态 static 是有区别的,静态变量是指只有一份存储空间,但值是可以改变的。
(1)final 变量
被 final 修饰的变量必须要初始化,并且变量在初始化之后不可改变。不可改变的意思是,对于基本数据类型来说是其值不可改变,对于对象变量来说是其引用不可改变,即不能再指向其他的对象。
(2)final 方法
被 final 修饰的方法不能被重写。
(3)final 类
被 final 修饰的类不能被继承。
final 和 static 修饰变量时的区别: static 作用于成员变量用来表示只保存一份副本,而 final 的作用是用来保证变量不可变,测试代码如下:
class A {
public final double i = Math.random();
public static double j = Math.random();
}
public class Test {
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
A a3 = new A();
// final 变量值不可变,不能再赋值
//a1.i = 2.0;// error:The final field A.i cannot be assigned
System.out.println(a1.i);
System.out.println(a1.j);
System.out.println(a2.i);
System.out.println(a2.j);
System.out.println(a3.j);
}
}
测试结果:
0.05777923657174122
0.3150414793053079
0.6102708080678539
0.3150414793053079
0.3150414793053079
由运行结果:j 是 static 变量,是类所拥有的,在 A 类被加载时只能初始化一次,因此三次打印,j 的值都是一样的;i 是 final 变量,但没有被 static 修饰,是对象所拥有的,在创建对象的时候被初始化,即在创建 a1 和 a2 时被初始化,所以 a1.i 和 a2.i 的值不同,但是两个值都不能再改变(不能再赋值)。