Static Variables and Methods:
The static modifier has such a profound impact on the behavior of a method or variable that we're treating it as a concept entirely separate from the other modifiers. To understand the way a static member works, we'll look first at a reason for using one. Imagine you've got a utility class with a method that always runs the same way; its sole function is to return, say, a random number. It wouldn't matter which instance of the class performed the method—it would always behave exactly the same way. In other words, the method's behavior has no dependency on the state (instance variable values) of an object. So why, then, do you need an object when the method will never be instance-specific? Why not just ask the class itself to run the method?
Let's imagine another scenario: Suppose you want to keep a running count of all instances instantiated from a particular class. Where do you actually keep that variable? It won't work to keep it as an instance variable within the class whose instances you're tracking, because the count will just be initialized back to a default value with each new instance. The answer to both the utility-method-always-runs-the-same scenario and the keep-a-running-total-of-instances scenario is to use the static modifier. Variables and methods marked static belong to the class, rather than to any particular instance. In fact, you can use a static method or variable without having any instances of that class at all. You need only have the class available to be able to invoke a static method or access a static variable. static variables, too, can be accessed without having an instance of a class. But if there are instances, a static variable of a class will be shared by all instances of that class; there is only one copy.
The following code declares and uses a static counter variable:
The static modifier has such a profound impact on the behavior of a method or variable that we're treating it as a concept entirely separate from the other modifiers. To understand the way a static member works, we'll look first at a reason for using one. Imagine you've got a utility class with a method that always runs the same way; its sole function is to return, say, a random number. It wouldn't matter which instance of the class performed the method—it would always behave exactly the same way. In other words, the method's behavior has no dependency on the state (instance variable values) of an object. So why, then, do you need an object when the method will never be instance-specific? Why not just ask the class itself to run the method?
Let's imagine another scenario: Suppose you want to keep a running count of all instances instantiated from a particular class. Where do you actually keep that variable? It won't work to keep it as an instance variable within the class whose instances you're tracking, because the count will just be initialized back to a default value with each new instance. The answer to both the utility-method-always-runs-the-same scenario and the keep-a-running-total-of-instances scenario is to use the static modifier. Variables and methods marked static belong to the class, rather than to any particular instance. In fact, you can use a static method or variable without having any instances of that class at all. You need only have the class available to be able to invoke a static method or access a static variable. static variables, too, can be accessed without having an instance of a class. But if there are instances, a static variable of a class will be shared by all instances of that class; there is only one copy.
The following code declares and uses a static counter variable:
class Frog {
static int frogCount = 0; // Declare and initialize
// static variable
public Frog() {
frogCount += 1; // Modify the value in the constructor
}
public static void main (String [] args) {
new Frog();
new Frog();
new Frog();
System.out.println("Frog count is now " + frogCount);
}
}
In the preceding code, the static frogCount variable is set to zero when the Frog class is first loaded by the JVM, before any Frog instances are created! (By the way, you don't actually need to initialize a static variable to zero; static variables get the same default values instance variables get.) Whenever a Frog instance is created, the Frog constructor runs and increments the static frogCount variable. When this code executes, three Frog instances are created in main(), and the result is Frog count is now 3
Now imagine what would happen if frogCount were an instance variable (in other words, nonstatic):
class Frog {Now imagine what would happen if frogCount were an instance variable (in other words, nonstatic):
int frogCount = 0; // Declare and initialize
// instance variable
public Frog() {
frogCount += 1; // Modify the value in the constructor
}
public static void main (String [] args) {
new Frog();
new Frog();
new Frog();
System.out.println("Frog count is now " + frogCount);
}
}
When this code executes, it should still create three Frog instances in main(),
but the result is...a compiler error! We can't get this code to compile, let alone run.
The JVM doesn't know which Frog object's frogCount you're trying to access. The problem is that main() is itself a static method, and thus isn't running against any particular instance of the class, rather just on the class itself. A static method can't access a nonstatic (instance) variable, because there is no instance! That's not to say there aren't instances of the class alive on the heap, but rather that even if there are, the static method doesn't know anything about them. The same applies to instance methods; a static method can't directly invoke a nonstatic method. Think static = class, nonstatic = instance. Making the method called by the JVM (main()) a static method means the JVM doesn't have to create an instance of your class just to start running code.
but the result is...a compiler error! We can't get this code to compile, let alone run.
The JVM doesn't know which Frog object's frogCount you're trying to access. The problem is that main() is itself a static method, and thus isn't running against any particular instance of the class, rather just on the class itself. A static method can't access a nonstatic (instance) variable, because there is no instance! That's not to say there aren't instances of the class alive on the heap, but rather that even if there are, the static method doesn't know anything about them. The same applies to instance methods; a static method can't directly invoke a nonstatic method. Think static = class, nonstatic = instance. Making the method called by the JVM (main()) a static method means the JVM doesn't have to create an instance of your class just to start running code.
0 comments:
Post a Comment