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()
就是一个利用工厂方法获取对象的例子。
参考 接口与工厂