. . .there’s no there there.
—GERTRUDE STEIN
A class can have variables that are static as well as methods that are static.
Static variables and static methods belong to a class as a whole and not to an individual object. In this section, we show you how to define static variables and static methods.
Static Variables
We have already used static variables in one special case, namely, in the definition of named constant values such as the following:
public static final double FEET_PER_YARD = 3;
Only one copy of FEET_PER_YARD exists. It belongs to the class, so individual objects of the class that contains this definition do not have their own versions of this constant. Instead, they have access to and share this one constant.
This particular static variable cannot change in value—it is a constant—
because its definition includes the keyword final. However, we can have static variables that can change in value. They are declared like instance variables, but with the keyword static. For example, the following static variable can change in value:
private static int numberOfInvocations;
A static variable can be public or private; however, like instance variables, static variables that are not constants should normally be private and should be accessed or changed only via accessor and mutator methods.
■ PROGRAMMING TIP Write Interdependent Constructors When writing multiple constructors for a class, identify one that the others can call by using this. Writing constructors in this way places the actual initialization in one place, making the class easier to maintain and less prone to error. Chapter 8 will talk more about this way of writing constructors. ■
EXAMPLE
public Pet3(String initialName) {
this(initialName, 0, 0);
}
Static variables are shared by all objects of a class
Static variables that are not constants should be private
390 CHAPTER 6 / More About Objects and Methods
There is only one variable named numberOfInvocations, and it can be accessed by every object of its class. This means that the static variable could allow objects to communicate with one another or perform some joint action. For example, each method in its class could increment numberOfInvocations and so track how many method calls are made by all objects of the class.
The next section gives an example of a static variable in use. You can initialize a static variable in the same way that you initialize a named constant, except that you omit the keyword final: private static int
numberOfInvocations = 0;
Static variables are also called class variables.
%P OPU DPOGVTF UIF UFSNclass variable—which simply means a static variable within a class—
with the notion of a variable of a class type—
which means a variable whose type is a class, that is, a variable that is used to name objects of a class. Both static variables and instance variables are sometimes called fields or data members.
ASIDE System.outIs a Static Object Chapter 2 mentioned that out is an object of the class System. But it is actually a static constant that has the following declaration:
public static final PrintStream out;
Sinceout is public, we can access it by name outside of the class System. However, when we do so we must precede its name with System and a dot, as in System.out. The statement just shown creates out as an object of the class PrintStream, which is in the Java Class Library. The methods print and println are methods in this class. To invoke these methods, you write the name of an object of PrintStream, a dot, and the name of the method. So when we write System.out.println(), for example, we are invoking the method println of the objectout.
RECAP Static, or Class, Variables
The declaration of a static variable contains the keyword static. A static variable is shared by all the objects of its class.
REMEMBER Three Kinds of Variables
Java has three kinds of variables: local variables, instance variables, and static (class) variables.
Static Methods
Sometimes you need a method that has no relation to an object of any kind.
For example, you might need a method to compute the maximum of two integers, or a method to compute the square root of a number, or a method to convert a letter character from lowercase to uppercase. None of these methods
REMEMBER A Class of Static Methods
You can create a collection of static methods to perform computations that are somehow related and group them within a single class.
LISTING 6.5 Static Methods /**
Class of static methods to perform dimension conversions.
*/
public class DimensionConverter {
public static final int INCHES_PER_FOOT = 12;
public static double convertFeetToInches(double feet) {
return feet * INCHES_PER_FOOT;
}
public static double convertInchesToFeet(double inches) {
return inches / INCHES_PER_FOOT;
} }
A static constant; it could be private here.
has any obvious object to which it should belong. In these cases, you can define the method as static. When you define a static method, the method is still a member of a class, since you define it in a class, but the method can be invoked without using any object. You normally invoke a static method by using the class name instead of an object name.
For example, Listing 6.5 contains a class named DimensionConverter, which defines two static methods for converting between measurements in feet and measurements in inches. You define a static method in the same way that you would define any other method, but you add the keyword static to UIFNFUIPETIFBEJOH
The following examples show how these methods are called:
double feet = DimensionConverter.convertInchesToFeet(53.7);
double inches = DimensionConverter.convertFeetToInches(2.6);
When you call a static method, you write the class name instead of an object name. Listing 6.6 shows these methods in use in a complete program.
Although you could create an object of the class DimensionConverter and use it to invoke either static method in the class, doing so can be confusing to programmers reading your code.
Invoke a static method using the class name, not an object name
Calling a static method
392 CHAPTER 6 / More About Objects and Methods
LISTING 6.6 Using Static Methods import java.util.Scanner;
/**
Demonstration of using the class DimensionConverter.
*/
public class DimensionConverterDemo {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a measurement in inches: ");
double inches = keyboard.nextDouble();
double feet =
DimensionConverter.convertInchesToFeet(inches);
System.out.println(inches + " inches = " + feet + " feet.");
System.out.print("Enter a measurement in feet: ");
feet = keyboard.nextDouble();
inches = DimensionConverter.convertFeetToInches(feet);
System.out.println(feet + " feet = " + inches + " inches.");
} }
Sample Screen Output
Enter a measurement in inches: 18 18.0 inches = 1.5 feet.
Enter a measurement in feet: 1.5 1.5 feet = 18.0 inches.
In the class DimensionConverter in Listing 6.5, both the named constant and the two methods are static and public. (We could have declared the named constant INCHES_PER_FOOT as private if we did not want it to be accessible outside of this class.) Although this class declares no instance variables, a class can have instance variables, static variables, static constants, static methods, and non-static methods. While such a combination is possible, you do need to be a bit careful.
-FUTTUVEZUIFJOUFSBDUJPOBNPOHWBSJPVTTUBUJDBOEOPOTUBUJDNFNCFST of a class by examining the class SavingsAccount in Listing 6.7. This class maintains the balance of individual savings accounts, and so it declares an instance variable balance. All accounts can earn the same rate of interest, so the class has a static variable interestRate. The class also counts the number of accounts opened by using the static variable numberOfAccounts.
LISTING 6.7 Mixing Static and Non-static Members in a Class (part 1 of 2)
import java.util.Scanner;
/**
Class with static and nonstatic members.
*/
public class SavingsAccount {
private double balance;
public static double interestRate = 0;
public static int numberOfAccounts = 0;
public SavingsAccount() {
balance = 0;
numberOfAccounts++;
}
public static void setInterestRate(double newRate) {
interestRate = newRate;
}
public static double getInterestRate() {
return interestRate;
}
public static int getNumberOfAccounts() {
return numberOfAccounts;
}
public void deposit(double amount) {
balance = balance + amount;
}
public double withdraw(double amount) {
if (balance >= amount)
balance = balance - amount;
else
amount = 0;
return amount;
}
(continued) Static variables
A static method can reference a static variable but not an instance variable.
A nonstatic method can reference a static variable.
An instance variable (nonstatic)
394 CHAPTER 6 / More About Objects and Methods
The class has static set and get methods for the interest rate, a static get method for the number of accounts, and non-static methods for making deposits, making withdrawals, adding interest, and getting an account balance. Lastly, the class has a static method that displays the balance of any given savings account.
Within the definition of a static method, you cannot reference an instance variable. Because a static method can be invoked without using any object name, there is no instance variable to refer to. For example, the static method setInterestRate can reference the static variable interestRate but not the instance variable balance, which is not static.
A static method—and remember that main is a static method—cannot call a non-static without having an instance of a class to use in the invocation. For example, the static method showBalance has an object of SavingsAccount as its parameter. It uses this object to invoke the non-static method getBalance. The only way showBalance can get data for the balance of an account is from an object that represents that account.
The non-static addInterest can reference the static variable interestRate or call the static method getInterestRate. Preceding the method name in the invocation of getInterestRate with the name of the class and a dot is optional, since the methods are all within SavingsAccount. Notice that the constructor also is not static. It increments the static variable numberOfAccounts to count the number of times it is called, thus counting the number of new account objects.
Listing 6.8 shows a sample program that demonstrates the class SavingsAccount. Because we use a doubleWBSJBCMFUPSFQSFTFOUBOBDDPVOUT CBMBODFPOFPGUIFEPMMBSBNPVOUTTIPXOJOUIFTDSFFOPVUQVUJTOUBTOFBU as it could be. Somewhat later in this chapter, we will present one remedy for this situation.
LISTING 6.7 Mixing Static and Non-static Members in a Class (part 2 of 2)
public void addInterest() {
double interest = balance * interestRate;
// you can replace interestRate with getInterestRate() balance = balance + interest;
}
public double getBalance() {
return balance;
}
public static void showBalance(SavingsAccount account) {
System.out.print(account.getBalance());
} }
A nonstatic method can reference a static variable or call a static method.
A static method cannot call a nonstatic method unless it has an object to do so.
A static method cannot reference an instance variable
A static method can call only a static method main is a static method A non-static method can reference any variable or call any method within its class
LISTING 6.8 Using Static and Non-static Methods public class SavingsAccountDemo
{
public static void main(String[] args) {
SavingsAccount.setInterestRate(0.01);
SavingsAccount mySavings = new SavingsAccount( );
SavingsAccount yourSavings = new SavingsAccount( );
System.out.println("I deposited $10.75.");
mySavings.deposit(10.75);
System.out.println("You deposited $75.");
yourSavings.deposit(75.00);
System.out.println("You deposited $55.");
yourSavings.deposit(55.00);
double cash = yourSavings.withdraw(15.75);
System.out.println("You withdrew $" + cash + ".");
if (yourSavings.getBalance() > 100.00) {
System.out.println("You received interest.");
yourSavings.addInterest();
}
System.out.println("Your savings is $" + yourSavings.getBalance());
System.out.print("My savings is $");
SavingsAccount.showBalance(mySavings);
System.out.println();
int count = SavingsAccount.getNumberOfAccounts();
System.out.println("We opened " + count + " savings accounts today.");
} }
Screen Output I deposited $10.75.
You deposited $75.
You deposited $55.
You withdrew $15.75.
You received interest.
Your savings is $115.3925 My savings is $10.75
We opened 2 savings accounts today.
396 CHAPTER 6 / More About Objects and Methods
GOTCHA Invoking a Non-static Method from Within a Static Method
You will often hear people say, “You cannot invoke a non-static method within the definition of a static method.” This is not quite true, however.
A more precise, and correct, statement is, “You cannot invoke a non-static method within a static method unless you have an object to use in the call of the non-static method.” Put another way, in the definition of a static method—such asmain—you cannot use an instance variable or method that has an implicit or explicit this as its calling object. Since a static method can be invoked without any calling object, it can be invoked when there is no meaning for this. To paraphrase Gertrude Stein, in a static method, “there is no this
there.” ■
RECAP Static Methods
If you place the keyword static in the heading of the definition of a method, the method can be invoked using the class name in place of an object name. Since it does not need an object in its invocation, a static method cannot reference an instance variable of the class. It also cannot invoke a non-static method of the class, unless it has an object of the class and uses this object in the invocation. In other words, the definition of a static method cannot use an instance variable or a non-static method that has an implicit or explicit this as its calling object.
S E L F - T E S T Q U E S T I O N S
6. What is the difference between a static variable and an instance variable?
7. Can a class contain both instance variables and static methods?
8. Can you reference a static variable by name within the definition of a static method without using a class name and a dot?
9. Can you reference an instance variable by name within the definition of a static method without using a class name or an object name and a dot?
10. Can you reference a static variable by name within the definition of a non-static method without using a class name and a dot?
11. Can you reference an instance variable by name within the definition of a non-static method without using a class name or an object name and a dot?
Using static and non-static methods
VideoNote
12. Is the following valid, given the class DimensionConverter in Listing 6.5?
DimensionConverter dc = new DimensionConverter();
double inches = dc.convertFeetToInches(2.5);
13. Can a class contain both static and non-static methods?
14. Can you invoke a non-static method within a static method?
15. Can you invoke a static method within a non-static method?
16. Is the following valid, given the class SavingsAccount in Listing 6.7?
SavingsAccount.addInterest();
Dividing the Task of a main Method into Subtasks
8IFO B QSPHSBNT MPHJD JT JOWPMWFE PS JUT DPEF JT SFQFUJUJWF ZPV DBO DSFBUF static methods to accomplish various subtasks and invoke these methods from your main method. Recall from the previous chapter the program in Listing 5.18 that we used to test the equals methods in the class Species. Listing 6.9 reproduces that program here. We have highlighted two sections of code that are identical. Rather than repeat this code, we could place it into a static method and invoke it twice within the main method. We have made this revision in Listing 6.10 and have also created an additional method from the code within the unfilled colored rectangle in Listing 6.9. Our two new helping methods are static as well as private.
The method main can invoke other static methods
■ PROGRAMMING TIP Helping Methods for a mainMethod Simplify the logic of a main method within an application program by having it call helping methods. These methods should be static, since main is static.
As helping methods, they likely should be private as well. ■
REMEMBER mainIs a Static Method
Since the method main is static, you must adhere to the points made in the previous section about static methods. Generally, a static method can invoke only static methods and reference only static variables. It cannot invoke a non-static method of the same class unless you have an object of the class to use in the invocation.
398 CHAPTER 6 / More About Objects and Methods
LISTING 6.9 Amain Method with Repetitive Code public class SpeciesEqualsDemo
{
public static void main(String[] args) {
Species s1 = new Species(), s2 = new Species();
s1.setSpecies("Klingon Ox", 10, 15);
s2.setSpecies("Klingon Ox", 10, 15);
if (s1 == s2)
System.out.println("Match with ==.");
else
System.out.println("Do Not match with ==.");
if (s1.equals(s2))
System.out.println("Match with the method equals.");
else
System.out.println("Do Not match with the method "+
"equals.");
System.out.println("Now change one Klingon Ox to "+
"lowercase.");
s2.setSpecies("klingon ox", 10, 15); //Use lowercase if (s1.equals(s2))
System.out.println("Match with the method equals.");
else
System.out.println("Do Not match with the method "+
"equals.");
} }
Adding a main Method to a Class
So far, whenever we have written a main method, it was by itself in its own class definition within a separate file. However, sometimes it makes sense to have a main method within a class definition. The class can then be used for two purposes: It can be used to create objects in other classes, or it can be run as a program. For example, you can write a main method inside the definition of the class Species, which is given in Listing 5.19 of the previous chapter.
The result is shown in Listing 6.11.
After redefining the class Species in this way, running it as a program causes the main method to be invoked. When Species is used as an ordinary class to create objects, the main method is ignored.
Since a main method is static, it cannot contain an invocation of a non- static method of the same class unless it has an object of the class and uses it in the invocation of the non-static method. The main method in Listing 6.11 Any class can
have a main method
invokes the methods of the class Species by first creating an object of the class Species BOE UIFO VTJOH JU UP JOWPLF PUIFS NFUIPET %PJOH TP JT OFDFTTBSZ even though the main method is inside the definition of the class Species. LISTING 6.10 Amain Method That Uses Helping Methods public class SpeciesEqualsDemo
{
public static void main(String[] args) {
Species s1 = new Species(), s2 = new Species();
s1.setSpecies("Klingon Ox", 10, 15);
s2.setSpecies("Klingon Ox", 10, 15);
testEqualsOperator(s1, s2);
testEqualsMethod(s1, s2);
System.out.println("Now change one Klingon Ox to "+
"lowercase.");
s2.setSpecies("klingon ox", 10, 15); //Use lowercase testEqualsMethod(s1, s2);
}
private static void testEqualsOperator(Species s1, Species s2) {
if (s1 == s2)
System.out.println("Match with ==.");
else
System.out.println("Do Not match with ==.");
}
private static void testEqualsMethod(Species s1, Species s2) {
if (s1.equals(s2))
System.out.println("Match with the method equals.");
else
System.out.println("Do Not match with the method "+
"equals.");
} }
On the Web, this class is SpeciesEqualsDemo2.
■ PROGRAMMING TIP Add a mainMethod to a Class to Test It You should not place just any main method in a class definition that is to be used as a regular class to create objects. However, placing a small diagnostic main method inside of your class definition provides a handy way to test it.
%PJOH TP BMTP BMFSUT PUIFS QSPHSBNNFST BCPVU UIF UFTUT ZPV IBWF EPOF 8F
talk more about testing later in this chapter. ■
400 CHAPTER 6 / More About Objects and Methods
LISTING 6.11 Placing a main Method in a Class Definition import java.util.Scanner;
public class Species {
private String name;
private int population;
private double growthRate;
<The methods readInput, writeOutput, predictPopulation, set- Species, getName, getPopulation, getGrowthRate, and equals go here. They are the same as in Listing 5.19.>
public static void main(String[] args) {
Species speciesToday = new Species( );
System.out.println("Enter data on today's species:");
speciesToday.readInput( );
speciesToday.writeOutput( );
System.out.println("Enter number of years to project:");
Scanner keyboard = new Scanner(System.in);
int numberOfYears = keyboard.nextInt( );
int futurePopulation =
speciesToday.predictPopulation(numberOfYears);
System.out.println("In " + numberOfYears +
" years the population will be " + futurePopulation);
speciesToday.setSpecies("Klingon ox", 10, 15);
System.out.println("The new species is:");
speciesToday.writeOutput( );
} }
The Math Class
The predefined class Math provides you with a number of standard mathematical methods. This class is automatically provided when you use the Java language; no import statement is needed. Some of the methods in the classMath are described in Figure 6.3. All of these methods are static, which means that you do not need—and in fact have no real use for—an object of the class Math. You normally call these methods by using the class name, Math, in place of an object name. For example, the following displays the maximum of the two numbers 2 and 3.
int ans = Math.max(2, 3);
System.out.println(ans);
The class Math contains a collection of mathematical methods and constants