final实例域
将实例域定义为final。构建对象时必须初始化这样的域。也就是说,必须确保在每一构造器执行之后,这个域的值被设置,并且在后面的操作中,不能够在对他进行修改。例如在Employee类中的name域声明为final,因为在对象构建之后,这个值不会再被修改,即没有setName方法。
class Employee
{
private final String name;...
}
final修饰大多用于基本数据类型域,或不可变类的域(如果类中的每个方法都不会改变其对象,这种类就是不可变类。例如,String类就是一个不可变的类)。对于可变的类使用final修饰符可能会对读者造成混乱。
静态域
如果将域定义为static,每一个类只有这样的一个域。而每一个对象对于所有的实例域却都有自己的一份拷贝。例如,假定需要给每一个雇员赋予唯一的标识码。这里给Employee类添加一个实例域id和一个静态域nextId。class Employee
{
public static int nextId = 20;private int id;...
}
现在,每一个雇员对象都有自己的一个id域,但这个类的所有实例域共享一个nextId域。换句话说,如果有1000个Employee类的对象,则有1000个实例域id。但是只有一个静态域nextId。即使没有一个雇员对象,静态域nextId也是存在的。它属于类,而不属于任何独立的对象。
静态常量
静态变量使用的比较少,但是静态常量却使用的比较多。例如,在Math类中定义了一个静态常量
public class Math{
……
public static final double PI=3.14159265358979323864;
……
}
在程序中可以使用Math.PI类的形式来获得这个常量。如果关键字static省略,pi就变成Math类的一个实例域。需要通过Math类的对象访问PI,并且每一个Math对象都有他自己的一份拷贝。另一个多次使用的静态常量是System.out。他在System类中的声明:
public class System
{
...
public static final PintStream out=nullPrintStream();
...
}因为每一个类对象都可以对公有域进行修改。所以最好不要将域设计为public,然而公有常量却没有问题。因为out被声明为final,所以不允许再将其他打印刘付给他:
静态方法
静态方法是一种不能向对象实施操作的方法。例如,Math类的paw方法就是一个静态方法。在运算时不适用任何的Math对象。换句话说没有隐式的参数,可以认为静态方法没有隐式参数的方法(在一个静态的方法中,this参数表示这个方法的隐式参数)因为静态方法不能操作对象,所以不能在静态方法中访问实例域。但是静态方法可以访问自身的类中的静态域。
Factory方法
静态方法还有一种常用的用途。NumberFormat类使用factory方法产生不同风格的格式对象。
NumberFormat currencyFormatter=NumberFormat.getCurrencyInstance();
NumberFormat percentFormatter=NumberFormat.getPercentInstance();
double x=0.1;
System.out.println(currencyFormatter.format(x));//¥0.10
System.out.println(percentFormatter.format(x));//10%
为什么NumberFormat类不利用构造器完成这些操作呢?主要原因有两种:1、无法命名构造器。构造器的名字必须与类名相同。但是,这里希望得到的货币的实例和百分比实例采用不同的名字。2、当使用构造器时,无法改变所构造的对象类型。而factory方法将返回一个DecimalFormat类对象,这是NumberFormat的子类。
main方法
main方法也是一个静态的方法,他不对任何对象进行操作。其实在启动程序时没有任何一个对象。静态的main方法将执行并创建程序所需要的对象。