Static and Instance Members
A simple name inside a method is resolved first against local variables and parameters in scope, and only then against member variables of the class.
One Word, Several Possible Meanings
Suppose you are reading the body of a method in a class you wrote and you see a single word, such as amount, standing alone on a line. Nothing in that line tells you which variable or method it names. It might be a variable created inside the method, a value passed in from outside, or a variable that belongs to the object the method is part of. Java has to settle this question every time it meets a simple name, and the answer depends on a set of rules about where names are visible.
What do you think happens?
Inside an instance method, a simple name test1 appears. The class also has an instance variable called test1, and the method has a local variable also called test1 declared earlier in its body. Which variable does test1 refer to?
Reveal answer
The local variable test1 declared inside the method
Java first searches the local variables and parameters that are in scope at the point where the name appears. Only if none of them matches does it treat the name as a member variable of the class.
This article walks through the search rules that Java follows for simple names, explains the two kinds of members a class can have, and then introduces the special variable this, which gives you a precise way to say which object you mean.
Searching Outward for a Simple Name
Think of a simple name as a question that Java answers by searching outward. Inside a method, the first place Java looks for a simple variable name is among the local variables and parameters that are in scope at that point. A variable is in scope when its declaration is in effect at the exact place in the source code where the name appears. If such a local variable or parameter exists, the name refers to it. If none exists, Java moves on and treats the name as a member variable of the class in which the reference occurs.
The flowchart shows the order of the search. The local search always comes first. A class member is considered only when no local variable or parameter with that name is in scope. The same idea applies to methods, with one difference: a simple method name must refer to a method defined in the same class, so the search for a method name never reaches into a different class without a more explicit reference.
Shadowing a Member With a Parameter
The rule that locals are searched first has a visible consequence. When a parameter has the same name as an instance variable, the simple name inside the method refers to the parameter. The example below is an original illustration, not taken from the source. It has one instance variable and one method that receives a parameter with the same name.
10
5- int amount = 5; is an instance variable, a member of the class
- int amount in the parameter list is a parameter, which is in scope throughout the method body
- The first println uses the simple name amount, so Java finds the parameter first and prints 10
this.amountuses the full name, so it reaches the instance variable in the object running show, printing 5
Tracing the name amount
Given the Counter class above, what does Java decide each time it meets the name amount inside show?
- 1Step 1: Check the local search
Java looks for a local variable or parameter named amount that is in scope at the line. The parameter amount is in scope throughout the method body, so the search stops here.
- 2Step 2: Resolve the first line
The first println uses the simple name amount. The search found the parameter, so the name refers to the value 10 that was passed in.
- 3Step 3: Resolve the second line
The second println uses
this.amount. This is a full name that points at the instance variable of the object running show, which holds 5.
The method prints 10 and then 5. The same spelling, amount, refers to two different things depending on whether this. is written in front of it.
Static Versus Instance Members
A member of a class is a variable or method declared inside the class but outside any single method. Members come in two kinds, and the difference between them shapes everything that follows. Static members belong to the class as a whole. Instance members belong to each individual object created from the class, and each object has its own copy.
The diagram captures the core difference. A static variable is attached to the class, so there is one of it no matter how many objects exist. An instance variable is attached to an object, so every object carries its own version. The source describes this distinction through the names you write: a static member is reached through a full name of the form class name dot simple name, while an instance member needs a reference to the object it belongs to.
3- static int total belongs to the class, so there is a single total shared by all Counter objects
- int amount belongs to each object, so a and b each have their own amount
a.bump()runs twice andb.bump()runs once; each call increments total, so total becomes 3Counter.reportTotal()is called through the class name, because it is a static method
Calling Static and Instance Members
| Member kind | Where it belongs | Full name form | Needs an object? |
|---|---|---|---|
| Static variable or method | The class as a whole | ClassName.name | No, the class name is enough |
| Instance variable or method | Each object created from the class | objectReference.name | Yes, a reference to the object |
| Instance member used inside its own instance method | The object running that method | this.name or a simple name | Supplied when the method runs |
Static and instance members differ in what they belong to and in how they are reached.
Notice the last row. Inside an instance method, you may write a simple name for an instance member, and Java supplies the object automatically when the method runs. Outside the class, or in a static context, you must make the object explicit or use the class name for static members.
The this Reference
Sometimes a method needs to name the object it belongs to explicitly. The simple name approach leaves that unanswered, so Java provides a special variable named this. Inside the source code of an instance method, this refers to the object that contains the method. Its purpose is to mean this object, the one this very method is part of. The value of this is not something you assign; the computer sets it automatically each time an instance method starts running.
The diagram shows the two routes. The full name this.amount goes through this to the object running the method and then to its instance variable. The simple name amount is resolved by the local search first, so it reaches the parameter. With this in hand, you can write full names for members of the same object: if var is an instance variable in the object that holds the method, then this.var is a full name for it, and if otherMethod() is an instance method in that same object, then this.otherMethod() can call it.
Parameter: Grace
Field: Ada
Announcing Adathis.nameis the instance variable of the object running greet, which holds Ada- The simple name name inside greet resolves to the parameter, which holds Grace
this.announce()calls the instance method in the same object, so it also sees Ada
Mistakes With Simple Names and this
Common mistake Assuming a simple name always refers to a class member
What it looks likeInside show(int amount), writing amount in the body and expecting the instance variable.
Why it failsJava searches local variables and parameters in scope first, so the parameter wins.
Do this insteadWrite this.amount when you mean the instance variable.
Common mistake Using an instance member's simple name inside a static method
What it looks likestatic void reportCount() { System.out.println(amount); } where amount is an instance variable.Why it failsA static method is not part of any object, so there is no object whose instance variable could be meant.
Do this insteadMake the static method use a static member, or pass an object in explicitly and use its reference.
Common mistake Thinking each object has its own copy of a static variable
What it looks likeCreating three Counter objects and expecting three separate total values.
Why it failsA static member belongs to the class, so one copy is shared by every object.
Do this insteadUse an instance variable if each object needs its own value.
Common mistake Trying to assign a value to this
Why it failsThe value of this is set by Java each time an instance method starts running; it is not something you assign.
Do this insteadUse this only to read the current object, for example this.amount or this.announce().
Tracing Names in a Small Class
Given the Counter class from the static members section, a student writes a new method reset() that sets total back to zero. Should reset() be static, and how should it refer to total? Explain your choice using the rule for where a static member belongs.
Hints
- Ask whether the value being reset belongs to the class as a whole or to each object.
- A static member is reached through the class name followed by a dot and the simple name.
In a class with an instance variable size and an instance method grow(int size), write the body of grow so that it adds the parameter size to the instance variable size. Which name refers to which value?
Hints
- The parameter is found first by the simple-name search.
- Use
this.sizeto reach the instance variable.
Key Takeaways
- A simple name inside a method is resolved first against local variables and parameters in scope, and only then against member variables of the class.
- Static members belong to the class and are reached through ClassName.name, while instance members belong to each object and need a reference to that object.
- A simple name for an instance member cannot be used in a static method, because a static method is not part of any object.
- Inside an instance method, this refers to the object running that method; Java sets it automatically, and you use
this.nameto write a full name for an instance variable or instance method in the same class.