Lesson 1.12 · Unit 1 · CED topic 1.14
Calling instance methods
In Lesson 1.10 you called methods on a class. Most methods in object-oriented code are different: they are called on an object, and they read or change the data stored in that particular object. Two Book objects with different page counts give different answers to the same getPages() call. This lesson is the lesson about the dot operator.
Learning objective.
- 1.14.A. Develop code to call instance methods and determine the result of these calls.
Essential knowledge.
- 1.14.A.1. Instance methods are called on objects of the class. The dot operator is used along with the object name to call instance methods.
- 1.14.A.2. A method call on a null reference will result in a NullPointerException.
The dot operator
Instance methods are called on objects of the class. You write the object's name, a dot, the method name, and the arguments.
objectName.methodName(arguments)
The object supplies the data; the arguments supply anything else the method needs. Use the Book class from Lesson 1.12.
Book novel = new Book("Dune", 612);
Book zine = new Book("Tips", 24);
System.out.println(novel.getPages());
System.out.println(zine.getPages());
System.out.println(novel.isLong());
System.out.println(zine.isLong());
612 24 true false
The same method name gives different answers because each call runs on a different object with different stored data.
What calls return and what they change
A method call has two possible effects, and you should always ask about both.
- A returned value.
getPages()returns anint. Use it in an expression or store it. The callnovel.getPages();on a line by itself computes the value and discards it. - A change to the object.
setPages(int)isvoid: it changes the stored data and returns nothing, so it appears as a statement by itself.
A method that only returns information about an object is called an accessor. One that changes the object's stored data is a mutator, and is often void. You will write both in Unit 3.
The null trap
A method call on a null reference results in a NullPointerException. The reference must refer to an object before you can use the dot operator on it.
Trace the object's state.
Book b = new Book("Poems", 80);
b.setPages(b.getPages() * 2);
System.out.println(b.getTitle() + ": " + b.getPages() + " pages");
System.out.println(b.isLong());
b.setPages(b.getPages() + 150);
System.out.println(b.isLong());
| After the statement | pages in the object |
|---|---|
new Book("Poems", 80) | 80 |
b.setPages(b.getPages() * 2) | 160 (the argument is evaluated first: 80 * 2) |
b.setPages(b.getPages() + 150) | 310 |
Poems: 160 pages false true
The argument b.getPages() * 2 is itself a method call, and it runs before setPages starts. 160 is not above 300, so isLong() is false at first; after the second change the count is 310, and it is true.
Which output do you get?
Book first = new Book("Alpha", 100);
Book second = new Book("Beta", 200);
Book alias = first;
alias.setPages(999);
second = first;
second.setPages(second.getPages() - 1);
System.out.println(first.getPages());
System.out.println(alias.getPages());
System.out.println(second.getTitle());
998 998 Alpha
alias = first makes both refer to the Alpha book, so setting 999 through alias changes Alpha. second = first then abandons the Beta book (its reference is overwritten) and also refers to Alpha. Subtracting 1 through second makes Alpha's count 998, and all three variables show it.
Three mistakes, three different reports.
public class Main {
public static void main(String[] args) {
int count = 5;
System.out.println(count.getPages());
}
}
Main.java:4: error: int cannot be dereferenced
System.out.println(count.getPages());
^
1 error
A primitive has no methods, so the dot operator cannot be applied to an int. Calling a method the class does not define (novel.getAuthor()) fails with cannot find symbol. And calling a method on an object that was never created, for example Book lost = null; lost.getTitle();, compiles but stops with a NullPointerException when it runs.
Expect traces that mix instance method calls with assignment of references, usually with aliasing: the question is how many objects exist and who sees a change. Ask of every call: does it return something I must use, does it change the object, and is the reference non-null? Questions about NullPointerException give you a reference that is null at the moment of the call.
- What is printed?
Book b = new Book("Maps", 50); b.setPages(70); System.out.println(b.getPages());Show answer
70. ThesetPagescall replaced the stored value 50 with 70. - What is printed?
Book b = new Book("Maps", 50); b.getPages(); b.setPages(b.getPages() + 5); System.out.println(b.getPages());Show answer
55. The first call returns 50 but the value is discarded and changes nothing. The second reads 50, adds 5, and stores 55. - How many
Bookobjects exist after this code, and what is printed?Book u = new Book("One", 10); Book v = new Book("Two", 20); Book w = u; w.setPages(30); System.out.println(u.getPages() + v.getPages() + w.getPages());Show answer
Two objects exist (
newwas called twice).uandwshare one, so aftersetPages(30)the sum is 30 + 20 + 30, which is80. The sum is anintaddition, so no digits are joined. - What happens when this code runs?
Book b = null; System.out.println(b.getTitle());
Show answer
A
NullPointerException.brefers to no object, so there is nothing to rungetTitleon. The code compiles; the failure happens at run time. - Which call stores the book's page count in an
intnamedn, givenBook b?Book b = new Book("Nine", 9); int n = b.getPages(); System.out.println(n);Show answer
int n = b.getPages();.getPagesis an instance method that returns anint, so you call it on the object and store the returned value. - True or false:
Book.getPages()is a correct way to ask the bookbfor its page count.Show answer
False.
getPagesis an instance method, so it must be called on an object (b.getPages()). Using the class name would be the form for astaticmethod.