static关键字

static关键字

static关键字意为“静态的”,其语义可以理解为“类的对象”(不要理解为Class对象),即不需要对象实例,可以直接通过类名.字段名的形式直接访问。

静态域 #

如果将一个域定义为static,那么每个类中都只有一个这样的域。参考如下例子:

1class Employee{
2  private static int nextId = 1;
3  private int id;
4  ...
5}

每一个Employee都有自己的一个id域,但是这个类的所有实例都共享一个nextId域。记住,即使没有Employee实例,静态域nextId也存在,它属于类而不属于任何对象。static域只在类加载的时候初始化一次,并且是先于非static域初始化的。

以下是一个简单的static关键字使用示例:

 1class Employee {
 2    static int nextId = 0;
 3    private int id;
 4    private String name;
 5    private int salary;
 6
 7    public Employee(String name, int salary) {
 8        this.name = name;
 9        this.salary = salary;
10    }
11
12    public void setId() {
13        this.id = nextId;
14        nextId++;
15    }
16
17    // getters
18    public static int getNextId() {
19        return nextId;
20    }
21
22    public int getId() {
23        return id;
24    }
25
26    public String getName() {
27        return name;
28    }
29
30    public int getSalary() {
31        return salary;
32    }
33}
34
35public class TestStatic {
36
37    public static void main(String[] args) {
38        Employee[] x = new Employee[3];
39        x[0] = new Employee("alex", 5000);
40        x[1] = new Employee("bob", 6000);
41        x[2] = new Employee("cup", 7000);
42
43        for (Employee e : x) {
44            e.setId();
45            System.out.println(
46                    "id = " + e.getId() +
47                            " name = " + e.getName() +
48                            " salary = " + e.getSalary());
49        }
50        System.out.println("the nextId is:  " + Employee.getNextId());
51    }
52}
53
54/*
55 * output:
56 * id = 0 name = alex salary = 5000
57 * id = 1 name = bob salary = 6000
58 * id = 2 name = cup salary = 7000
59 * the nextId is: 3
60 */// :~

静态常量 #

使用static final修饰的域可以作为静态常量,静态常量一般被声明为public,通常作为工具包的常量被其他类使用,如Math.PI

静态方法 #

使用static修饰的方法被称为静态方法,和静态常量一样,通常被声明为public,供其他类通过类名直接调用,如Math.pow(x,a)用于计算xa。静态方法不能访问对象域,因为其不能操作对象,但是其可以访问类的静态域。

尽管可以通过对象实例来调用类的静态方法,但是不推荐如此做,编译器也会提示应该使用类调用静态方法,因为对象尽管可以调用静态方法,但是往往静态方法的返回与对象无关(静态方法只能操作静态域,而不能操作对象属性),反而会造成混淆。

Java对于static的语义可以理解为:

属于类但是不属于对象的字段和方法

工厂方法 #

也是一种静态方法,不过其用来构造对象,因此被称为静态工厂方法,例如NumberFormat.getCurrencyInstance()就是一个利用工厂方法获取对象的例子。

参考 接口与工厂