In all sample programs that you have seen, the main method is tagged with the static modifier. We are now ready to discuss the meaning of this modifier. Static FieldsIf you define a field as static, then there is only one such field per class. In contrast, each object has its own copy of all instance fields. For example, let's suppose we want to assign a unique identification number to each employee. We add an instance field id and a static field nextId to the Employee class: class Employee { . . . private int id; private static int nextId = 1; } Every employee object now has its own id field, but there is only one nextId field that is shared among all instances of the class. Let's put it another way. If there are 1000 objects of the Employee class, then there are 1000 instance fields id, one for each object. But there is a single static field nextId. Even if there are no employee objects, the static field nextId is present. It belongs to the class, not to any individual object. NOTE
Let's implement a simple method: public void setId() { id = nextId; nextId++; } Suppose you set the employee identification number for harry: harry.setId(); Then the id field of harry is set, and the value of the static field nextId is incremented: harry.id = . . .; Employee.nextId++; ConstantsStatic variables are quite rare. However, static constants are more common. For example, the Math class defines a static constant: public class Math { . . . public static final double PI = 3.14159265358979323846; . . . } You can access this constant in your programs as Math.PI. If the keyword static had been omitted, then PI would have been an instance field of the Math class. That is, you would need an object of the Math class to access PI, and every Math object would have its own copy of PI. Another static constant that you have used many times is System.out. It is declared in the System class as: public class System { . . . public static final PrintStream out = . . .; . . . } As we mentioned several times, it is never a good idea to have public fields, because everyone can modify them. However, public constants (that is, final fields) are ok. Because out has been declared as final, you cannot reassign another print stream to it: System.out = new PrintStream(. . .); // ERROR--out is final NOTE
Static MethodsStatic methods are methods that do not operate on objects. For example, the pow method of the Math class is a static method. The expression: Math.pow(x, a) computes the power xa. It does not use any Math object to carry out its task. In other words, it has no implicit parameter. You can think of static methods as methods that don't have a this parameter. (In a non-static method, the this parameter refers to the implicit parameter of the method see page 112.) Because static methods don't operate on objects, you cannot access instance fields from a static method. But static methods can access the static fields in their class. Here is an example of such a static method: public static int getNextId() { return nextId; // returns static field } To call this method, you supply the name of the class: int n = Employee.getNextId(); Could you have omitted the keyword static for this method? Yes, but then you would need to have an object reference of type Employee to invoke the method. NOTE
You use static methods in two situations:
C++ NOTE
Factory MethodsHere is another common use for static methods. The NumberFormat class uses factory methods that yield formatter objects for various styles. 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% Why doesn't the NumberFormat class use a constructor instead? There are two reasons:
The main MethodNote that you can call static methods without having any objects. For example, you never construct any objects of the Math class to call Math.pow. For the same reason, the main method is a static method. public class Application { public static void main(String[] args) { // construct objects here . . . } } The main method does not operate on any objects. In fact, when a program starts, there aren't any objects yet. The static main method executes, and constructs the objects that the program needs. TIP
The program in Example 4-3 contains a simple version of the Employee class with a static field nextId and a static method getNextId. We fill an array with three Employee objects and then print the employee information. Finally, we print the next available identification number, to demonstate the static method. Note that the Employee class also has a static main method for unit testing. Try running both java Employee and java StaticTest to execute both main methods. Example 4-3. StaticTest.java1. public class StaticTest 2. { 3. public static void main(String[] args) 4. { 5. // fill the staff array with three Employee objects 6. Employee[] staff = new Employee[3]; 7. 8. staff[0] = new Employee("Tom", 40000); 9. staff[1] = new Employee("Dick", 60000); 10. staff[2] = new Employee("Harry", 65000); 11. 12. // print out information about all Employee objects 13. for (Employee e : staff) 14. { 15. e.setId(); 16. System.out.println("name=" + e.getName() 17. + ",,salary=" + e.getSalary()); 19. } 20. 21. int n = Employee.getNextId(); // calls static method 22. System.out.println("Next available Harry", 50000); 64. System.out.println(e.getName() + " " + e.getSalary()); 65. } 66. 67. private String name; 68. private double salary; 69. private int id; 70. private static int nextId = 1; 71. } |