在您看到的所有示例程序中,main方法都用static修饰符标记。 现在,我们准备讨论此修饰符的含义。
1.static字段
如果将字段定义为static,则每个类只有一个这样的字段。 相反,每个对象都有其自己的非静态实例字段的副本。 例如,假设我们要为每个员工分配一个唯一的标识号。 我们向Employee类添加一个实例字段ID和一个静态字段nextId:
class Employee
{
private static int nextId = 1;
private int id;
. . .
}
现在,每个Employee对象都有其自己的id 字段,但是在该类的所有实例之间只有一个nextId 字段可以共享。 让我们换一种说法。 如果Employee类有1,000个对象,则有1,000个实例字段ID,每个对象一个。 但是只有一个静态字段nextId。 即使没有Employee对象,静态字段nextId也会存在。 它属于该类,而不属于任何单个对象。
让我们实现一个简单的方法:
public void setId()
{
id = nextId;
nextId++;
}
假设您为harry设置了员工标识号
harry.setId();
然后,将harry的id字段设置为静态字段nextId的当前值,并增加静态字段的值
harry.id = Employee.nextId;
Employee.nextId++;
2.static常量
静态变量非常少见。 但是,静态常量更为常见,例如Math类定义了一个静态常量:
public class Math
{
. . .
public static final double PI = 3.14159265358979323846;
. . .
}
您可以在程序中以Math.PI的形式访问此常量。
如果省略了关键字static,则PI将成为Math类的实例字段。 也就是说,您将需要一个此类的对象来访问PI,并且每个Math对象都将拥有其自己的PI副本。您多次使用的另一个静态常量是System.out。 在System类中声明如下:
public class System
{
. . .
public static final PrintStream out = . . .;
. . .
}
正如我们多次提到的那样,拥有公共字段绝不是一个好主意,因为每个人都可以对其进行修改。 但是,可以使用公共常量(即final字段)。 由于out已被声明为final,因此您无法将其他print流分配给它:
System.out = new PrintStream(. . .); // ERROR--out is final
3.static方法
静态方法是不对对象进行操作的方法。 例如,Math类的pow方法是静态方法。 表达方式:
Math.pow(x, a)
计算xa。 它不使用任何Math对象来执行其任务,换句话说,它没有隐式参数。您可以将静态方法视为没有this参数的方法(在非静态方法中,this参数是指 到方法的隐式参数),Employee类的静态方法无法访问id实例字段,因为它不对对象进行操作。 但是,静态方法可以访问静态字段。 这是这种静态方法的示例:
public static int getNextId()
{
return nextId; // returns static field
}
要调用此方法,请提供类的名称:
int n = Employee.getNextId();
如果为此方法省略关键字static,则需要有一个类型为Employee的对象引用才能调用该方法。
在两种情况下使用静态方法:
•当方法不需要访问对象状态,因为所有必需的参数都作为显式参数提供时(例如:Math.pow)。
•当方法仅需要访问类的静态字段时( 例如:Employee.getNextId)。