Concepts / Constructors and Object Initialization in Java

Constructors and Object Initialization in Java

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.

  • Programming

A Single Word Standing Alone

Read the body of a method you have written and you may find a single word standing alone, such as amount. Nothing in that line says 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.

This article follows those rules step by step. You will trace how Java resolves a simple name, see why the same word can mean different things in different places, learn the difference between static and instance members, and finally meet the special variable this, which lets you say exactly which object you mean.

Tracing a Simple Name Step by Step

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, and the search stops there. If none exists, Java moves on and treats the name as a member variable of the class in which the reference occurs. The flowchart below traces this lookup for a bare name used inside a method.

Simple name seenfor example test1Local variable orparameter in scopewith that name?Refers to the localvariable or parametersearch stops hereMember variable ofthe class with thatname?Refers to the membervariablesearch stops herecheck firstyesnoyes
When the bare name test1 appears inside a method, which check runs first, and at which step does Java stop searching?

Methods follow a simpler pattern. 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.

Parameter Versus Field in One Method

The following class is an original illustration, not taken from the source. It has one instance variable named balance and one method that receives a parameter with the same name. Because the parameter is a local name in scope inside the method, a bare balance refers to the parameter. To reach the instance variable, the method must write this.balance.

Code walkthrough
class Account {
    int balance;

    void show(int balance) {
        System.out.println(balance);
        System.out.println(this.balance);
    }
}
  1. 1
    Line 2 declares the instance variable balance. It belongs to each Account object.
  2. 2
    Line 4 declares the method show with a parameter named balance.
  3. 3
    Line 5 uses the bare name balance. Java checks local variables and parameters in scope first, finds the parameter, and prints its value.
  4. 4
    Line 6 uses this.balance. The word this names the object running the method, and balance then refers to that object's instance variable.
  • int balance; is an instance variable, a member of the class
  • show(int balance) declares a parameter with the same name, which is in scope throughout the method body
  • The first println uses the bare name, so the lookup finds the parameter first
  • this.balance is a full name that reaches the instance variable of the object running show

Suppose the class is used like this: create an Account, set its balance field to 100, and then call show with the argument 20. Trace the two println lines against the lookup rules before you read the output.

What do you think happens?

Given a.balance = 100 and a call a.show(20), what does the first println(balance) print, and what does the second println(this.balance) print?

  • 20 then 100

  • 100 then 20

  • 100 then 100

  • 20 then 20

Reveal answer
Answer:

20 then 100

The bare name balance is resolved first against the parameter, which is in scope, so it prints 20. The full name this.balance refers to the instance variable of the object running show, which was set to 100, so it prints 100.

Static and 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 about how names are written. Some members belong to the class as a whole, and others belong to each individual object created from the class.

Class Counterstatic variable createdObject oneinstance variable countObject twoinstance variable countshares the one static variableshares the one static variable
Where does a static variable live compared with an instance variable, and how many copies exist when several objects are created?

The diagram shows the central distinction. A static member exists once, at the level of the class, and every object sees that same member. An instance member exists separately inside each object, so two objects built from the same class each hold their own copy of the variable.

Static and Instance Members in Code

The class below is an original illustration. It has a static variable created that is shared by the whole class, and an instance variable count that each object holds separately. The static method reportCreated uses the full name Counter.created, because it belongs to no object.

Code walkthrough
class Counter {
    static int created;
    int count;

    void bump() {
        count = count + 1;
    }

    static void reportCreated() {
        System.out.println(Counter.created);
    }
}
  1. 1
    Line 1 declares the static variable created. Only one exists, shared through the class.
  2. 2
    Line 2 declares the instance variable count. Each Counter object gets its own.
  3. 3
    Lines 4 to 6 define bump, an instance method. When bump runs on an object, the simple name count refers to that object's count.
  4. 4
    Lines 8 to 10 define reportCreated, a static method. It reads created through the full name Counter.created. If it tried to write count = count + 1, Java would reject it, because no object is running the static method.
  • static int created is one value for the whole class
  • int count is a separate value inside each Counter object
  • bump uses the simple name count, which resolves to the instance variable of the object running bump
  • reportCreated cannot use the simple name count, because a static method has no object to supply it

Mistakes Beginners Make with Member Names

The rules above are short, but they are easy to misapply when a method and a class share names. The most common errors are listed below with the correction for each.

  • Common mistake

    Assuming a bare name always means the instance variable

    What it looks like
    void show(int balance) { System.out.println(balance); } printing the parameter instead of the field
    Why it fails

    Java checks local variables and parameters in scope before member variables, so a parameter with the same name hides the field for bare-name use.

    Do this instead

    Write this.balance when you mean the instance variable of the current object.

  • Common mistake

    Using an instance variable by simple name inside a static method

    What it looks like
    static void tryBump() { count++; } in a class where count is an instance variable
    Why it fails

    A static method is not part of any object, so there is no object whose instance variable count could be meant.

    Do this instead

    Pass an object into the static method and use its full name, or make the member static if it truly belongs to the class.

  • Common mistake

    Thinking a static variable has a separate copy in each object

    Why it fails

    A static member belongs to the class, so all objects of that class refer to the same single value.

    Do this instead

    Reach the static member through its class name, for example Counter.created, and expect every object to see the same value.

  • Common mistake

    Believing this is a value you assign. The value of this is set by the computer each time an instance method starts running.

Using this to Name the Current Object

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 very object, the one this method is part of.

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. If otherMethod() is an instance method in that same object, then this.otherMethod() can call it. The value of this is not something you assign. The computer sets it each time an instance method starts running.

Running instancemethodshowthisthe object containing themethodAccount objectthe object running showbalanceinstance variable of thatobjectJava sets this automaticallyrefers toholds
Inside a method, which object does this point to, and how does this.balance reach the instance variable?

Predicting Name Resolution Before Running Code

Use the rules in this article to work through the following problem before checking your answer. Consider a class Tally with a static variable total and an instance variable hits. Its instance method record takes a parameter named hits and contains the lines: System.out.println(hits); then System.out.println(this.hits); then System.out.println(Tally.total);

MEDIUM

For a Tally object whose instance variable hits is 7, and where the call to record passes the argument 3, with total set to 12 through the class name, state the three printed values in order and name the rule that decides each one.

Hints
  • Start with the bare name hits. Ask first whether a local variable or parameter with that name is in scope.
  • For this.hits, ask which object is running record.
  • For Tally.total, remember that a static member is reached through the class name and belongs to the class.

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.
  • A simple method name must refer to a method defined in the same class, so method lookup does not reach into other classes without a more explicit reference.
  • Static members belong to the class and are reached through class name dot simple name, while instance members belong to each object and need a reference to that object.
  • The special variable this refers to the object containing the current instance method, and Java sets it automatically each time that method runs, so you can write this.var or this.method() to be explicit.