java
// Simple use of the "this" keyword
public class Leaf {
private int i = 0;
Leaf increment() {
i++;
return this;
}
void print() {
System.out.println("i = " + i);
}
public static void main(String[] args) {
Leaf x = new Leaf();
x.increment().increment().increment().print();
}
} ///:~
Because increment( ) returns the handle to the current object via the this keyword, multiple operations can easily be performed on the same object.
Calling constructors from constructors
When you write several constructors for a class, there are times when you’d like to call one constructor from another to avoid duplicating code. You can do this using the this keyword.
Normally, when you say this, it is in the sense of “this object” or “the current object,” and by itself it produces the handle to the current object. In a constructor, the this keyword takes on a different meaning when you give it an argument list: it makes an explicit call to the constructor that matches that argument list. Thus you have a straightforward way to call other constructors:
//: Flower.java
// Calling constructors with "this"
public class Flower {
private int petalCount = 0;
private String s = new String("null");
Flower(int petals) {
petalCount = petals;
System.out.println(
"Constructor w/ int arg only, petalCount= "
+ petalCount);
}
Flower(String ss) {
System.out.println(
"Constructor w/ String arg only, s=" + ss);
Chapter 4: Initialization & Cleanup
143
s = ss;
}
Flower(String s, int petals) {
this(petals);
//! this(s); // Can't call two!
this.s = s; // Another use of "this"
System.out.println("String & int args");
}
Flower() {
this("hi", 47);
System.out.println(
"default constructor (no args)");
}
void print() {
//! this(11); // Not inside non-constructor!
System.out.println(
"petalCount = " + petalCount + " s = "+ s);
}
public static void main(String[] args) {
Flower x = new Flower();
x.print();
}
} ///:~
The constructor Flower(String s, int petals) shows that, while you can call one constructor using this, you cannot call two. In addition, the constructor call must be the first thing you do or you’ll get a compiler error message.
This example also shows another way you’ll see this used. Since the name of the argument s and the name of the member data s are the same, there’s an ambiguity. You can resolve it by saying this.s to refer to the member data. You’ll often see this form used in Java code, and it’s used in numerous places in this book.
In print( ) you can see that the compiler won’t let you call a constructor from inside any method other than a constructor.
The meaning of sstatic
With the this keyword in mind, you can more fully understand what it means to make a method static. It means that there is no this for that particular method. You cannot call non-static methods from inside static methods2 (although the reverse is possible), and you can call a static method for the class itself, without any object. In fact, that’s primarily what a static method is for. It’s as if you’re creating the equivalent of a global function (from C).
Except global functions are not permitted in Java, and putting the static method inside a class allows it access to other static methods and to static fields.
Some people argue that static methods are not object-oriented since they do have the semantics of a global function; with a static method you don’t send a message to an object, 2 The one case in which this is possible occurs if you pass a handle to an object into the static method.
Then, via the handle (which is now effectively this), you can call non-static methods and access non-static fields. But typically if you want to do something like this you’ll just make an ordinary, non-static method.
144
Thinking in Java
www.BruceEckel.com
since there’s no this. This is probably a fair argument, and if you find yourself using a lot of static methods you should probably rethink your strategy. However, statics are pragmatic and there are times when you genuinely need them, so whether or not they are “proper OOP” should be left to the theoreticians. Indeed, even Smalltalk has the equivalent in its
“class methods.”
Cleanup: finalization and
garbage collection