静态字段就是将字段定义为 static 的字段,类的全部实例共享一个静态字段。静态字段属于类,而不属于任何单个对象。而对于非静态的实例字段,每一个对象都有本身的一个副本。java
class Employee { private static int nextId = 1; private int id; ... }
如今,每一个 Employee 对象都一个本身的 id 字段,但 Employee 类的全部实例将共享一个 nextId 字段。即便没有 Employee 对象,静态字段 nextId 也存在。它属于类,而不属于任何单个对象。ide
静态变量使用得比较少,但静态常量却很经常使用。例如,在 Math 类中定义了一个静态常量。单元测试
public final class Math { ... public static final double PI = 3.14159265358979323846; ... }
在程序中,能够用 Math.PI 来访问这个常量。测试
若是省略关键字 static,PI 就变成了 Math 类的一个实例字段。也就是说,须要经过 Math 类的一个对象来访问 PI,而且每个 Math 对象都有它本身的一个 PI 副本。ui
另外一个静态常量是 System.out。在 System 类中声明以下:this
public final class System { ... public static final PrintStream out = null; ... }
因为每一个类对象均可以修改公共字段,因此,最好不要有公共字段。然而,公共常量(即 final 字段)却没有问题。所以 out 被声明为 final,因此,不容许再将它从新赋值为另外一个打印流:
System.out = new PrintStream(...); // 错误,out 是 final 常量
code
注释: 若是查看 System 类,就会发现有一个 setOut 方法能够将 System.out 设置为不一样的流。你可能会感到奇怪,为何这个方法能够修改 final 变量的值。缘由在于,setOut 方法是一个原生方法,而不是在 Java 语言中实现的。原生方法能够绕过 Java 语言的访问控制机制。这是一种特殊的解决方案,在本身编写程序时不要模仿这种作法。orm
静态方法是不在对象上执行的方法。例如,Math 类的 pow 方法就是一个静态方法。表达式:
Math.pow(x, a)
会计算幂 x<sup>a</sup>。在完成计算时,它并不使用任何 Math 对象。换句话说,它没有隐式参数。对象
能够认为静态方法是没有 this 参数的方法(在一个非静态的方法中,this 参数指示这个方法的隐式参数)。ci
静态方法不能访问实例字段,由于静态方法不能在对象上执行操做。可是,静态方法能够访问静态字段。
class Employee { private static int nextId = 1; private int id; public static int getNextId(){ return nextId; // 返回静态字段 } ... }
能够提供类名来调用这个方法:
int n = Employee.getNextId();
注释:可使用对象调用静态方法,这是合法的。例如,若是 harry 是一个 Employee 对象,可使用 harry.getNextId()
替代 Employee.getNextId()
。不过,这种方式很容易形成混淆,其缘由是 getNextId 方法计算的结果与 harry 毫无关系。咱们建议使用类名而不是对象来调用静态方法。
在下面两种状况下使用静态方法:
静态方法还有另一种常见的用途。相似 LocalDate 和 NumberFormat 的类使用静态工厂方法(factory method)来构造对象。例如工厂方法 LocalDate.now 和 LocalDate.of。NumberFormat 类以下生成不一样风格的格式化对象。
NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(); NumberFormat percentFormatter = NumberFormat.getPercentInstance(); double x = 0.1; System.out.println(currencyFormatter.format(x)); // prints ¥0.10 System.out.println(percentFormatter.format(x)); // prints 10%
NumberFormat 类不利用构造器完成这些操做的两个主要缘由:
能够调用静态方法而不须要任何对象。例如,不须要构造 Math 类的任何对象,就能够调用 Math.pow。
main 方法是一个静态方法。
public class Application { public static void main(String[] args) { // 在这里构造对象 } }
main 方法不对任何对象进行操做。事实上,在启动程序时尚未任何一个对象。静态 main 方法将执行并构造程序所须要的对象。
每个类能够有一个 main 方法。这是经常使用于对类进行单元测试的一个技巧。
java.util.Objects 7
static <T> void requireNonNull(T obj)
若是 obj 为 null,会抛出一个 NullPointerException 异常而没有抛出消息。
static <T> void requireNonNull(T obj, Strimg message)
若是 obj 为 null,会抛出一个 NullPointerException 异常而抛出给定消息。
static <T> void requireNonNull(T obj, Supplier<Strimg> messageSupplier)
若是 obj 为 null,会抛出一个 NullPointerException 异常而抛出给定消息。
static <T> T requireNonNullElse(T obj, T defaultObj)
若是 obj 不为 null 则返回 obj,或者若是 obj 为 null 则返回默认对象。
static <T> T requireNonNullElseGet(T obj, Supplier<T> defaultSupplier)
若是 obj 不为 null 则返回 obj,或者若是 obj 为 null 则返回默认对象。