Before the questions, make sure you can: draw what happens in memory when an object is created
and when one reference is assigned to another; explain why == and equals give different
answers for objects; say exactly what a method can and cannot do to an object passed as an
argument; write a default and a parameterised constructor with the correct heading; state when
the compiler supplies a constructor for you and when it does not; use this(...) to chain
constructors; and read a chained call such as a.getB().getName().
Object creation, step by step
Student s1 = new Student("Ali", 65.5);
Student s1creates a reference variable; on its own it refers to no object (a field holdsnull; a local variable must be assigned before use).new Student(...)allocates the object and gives every field its default value.- The matching constructor runs and sets the fields.
- The address of the object is assigned to
s1.
The variable lives in the method's stack frame; the object lives on the heap. When the last reference to an object disappears, the object becomes eligible for garbage collection.
Assigning references, and equality
Student a = new Student("Ali", 60);
Student b = a; // ALIAS: one object, two names
Student c = new Student("Ali", 60);
a == b // true : same address
a == c // false : two distinct objects, even with identical data
a.equals(c) // false unless the class OVERRIDES equals
Inherited from Object, equals compares references, exactly like ==. A class that
wants value equality must override it:
public boolean equals(Object o) {
if (!(o instanceof Student)) return false;
Student other = (Student) o;
return this.id == other.id; // compare the identifying fields
}
Passing references as arguments
A method receives a copy of the reference. It may therefore call mutators and change the object's state, and the caller sees those changes. If it assigns a new object to the parameter, the caller's variable is unaffected — the same rule as for arrays in Chapter 9.
static void raise(Student s) { s.setGrade(s.getGrade() + 5); } // caller sees this
static void swapIn(Student s){ s = new Student("Other", 0); } // caller sees nothing
Constructors
public class Student {
private int id; private String name; private double grade;
public Student() { // default (no-argument) constructor
this("Unknown", 0.0); // may delegate with this(...)
}
public Student(String name, double grade) { // parameterised constructor
this.name = name;
this.grade = grade;
}
}
The rules that are examined:
- A constructor has exactly the class name and no return type at all —
not even
void.public void Student()is a perfectly legal method that happens to look like a constructor, and it is never called bynew. - If you declare no constructor, the compiler inserts a no-argument constructor that
does nothing. If you declare any constructor, it does not, so
new Student()then fails to compile unless you wrote that version yourself. - Constructors may be overloaded like any other method, on the parameter list.
this(...)calls another constructor of the same class and must be the first statement.- A class may not contain two constructors with the same parameter list, and therefore cannot have two no-argument constructors.
Correct forms to memorise:
| declare a default constructor | public MyClass() { ... } |
|---|---|
| declare a parameterised one | public Employee(String name, double salary) { this.name = name; ... } |
| create an object | MyClass obj = new MyClass(); |
| call an instance method | obj.update(3, "Hi!"); |
call a static method |
MyClass.greetings(); |
Overloaded methods in an instance context
The same signature rule applies as in Chapter 8: the name plus the parameter list must differ.
Overloading gives a family of related operations one honest name — add(int),
add(double), add(Student) — instead of addInt, addDouble, addStudent.
Method-call chaining
When a method returns a reference, another call can be attached to it:
String city = student.getAddress().getCity().toUpperCase();
Each call is evaluated left to right on the object returned by the previous one. If any of them
returns null, the next call throws a NullPointerException — which is why chains are
convenient but must be used with care. A method that returns this allows chained mutators:
order.setId(5).setQty(2);
Several classes working together
A realistic program has one class per concept plus a driver: Student, Course,
Enrolment, and SchoolApp with main. Each class is responsible for its own data;
the driver only orchestrates. Objects of one class routinely hold references to objects of
another — the idea developed as composition in Chapter 14.
==compares addresses;equalscompares content only if the class overrides it.- A constructor has no return type and is named after the class.
- Declare one constructor and you lose the free no-argument one.
this(...)must be the first statement of a constructor.- A method can mutate the object you pass it, but cannot replace it.
public void MyClass()— a method, not a constructor.MyClass obj = MyClass();—newis missing.- Adding a parameterised constructor and then calling
new MyClass()elsewhere. - Comparing two objects with
==and concluding that equal data means equal objects.
Ready? Close the notes and practise.
37 questions. Predict the output before you check — that is the skill the exam measures.