Summary: in this tutorial, you will learn about Java Object
which serves as the base class for all classes in Java.
Introduction to Java Object
The java.lang.Object
class is the base class of all classes in Java.
It means that when you define a class, it is implicitly a subclass of the Object
class. Also, the class automatically inherits a set of methods from the Object
class.
Suppose that you have a Person
class with two fields ssn
and name
, and a constructor:
class Person {
private String ssn;
private String name;
// Getters and setters (omitted for brevity)
public Person(String ssn, String name){
this.ssn = ssn;
this.name = name;
}
}
Code language: Java (java)
It is like defining the Person
class that extends the Object
class:
class Person extends Object {
// ...
}
Code language: Java (java)
However, it is not necessary since Java does it implicitly for us.
We’ll explore the methods provided by the Object
class and demonstrate how to override them to enhance the utility of your class.
Java Object methods
1) getClass()
The getClass()
method returns the runtime class of an object:
var cls = obj.getClass();
Code language: Java (java)
In this syntax, the cls
is an instance of the java.lang.Class
class.
Typically, you use the getClass()
method to check if two objects are instances of the same class.
If the getClass()
method of two objects returns the same value, they are instances of the same class.
For example, the following shows the return value of the getClass()
method of a Person
object:
public class App {
public static void main(String[] args) {
var person = new Person(
"212-15-8397",
"John Doe"
);
System.out.println(person.getClass());
}
}
Code language: Java (java)
Output:
class Person
Code language: Java (java)
2) equals(Object obj)
By default, the equals()
method returns true if two variables reference the same object.
Typically, you override the equals()
method to compare two objects by their contents.
The following example creates two Person objects with the same ssn
and name
, and uses the equals()
method to compare them:
public class App {
public static void main(String[] args) {
var p1 = new Person("212-15-8397", "John Doe");
var p2 = new Person("212-15-8397", "John Doe");
var result = p1.equals(p2);
System.out.println(result);
}
}
Code language: Java (java)
Output:
false
Code language: Java (java)
Since the Person class inherits the equals()
method from the Object class, the equals()
method checks if two variables reference the same object:
The program displays false because p1
and p2
variables reference different Person
objects even though they have the same ssn
and name
values.
import java.util.Objects;
class Person {
private String ssn;
private String name;
// Getters and setters (omitted for brevity)
public Person(String ssn, String name) {
this.ssn = ssn;
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || obj.getClass() != getClass()) {
return false;
}
Person other = (Person) obj;
return ssn.equals(other.ssn) && name.equals(other.name);
}
}
Code language: Java (java)
In this Person
class, we override the equals()
method of the Object
class that returns true if all the fields of the of the Person
objects are equal.
First, check if the object being compared is the same as the current instance and return true if they are the same reference:
if (this == obj) return true;
Code language: Java (java)
Second, return false if the object being compared is null or if its class differs from the class of the current instance:
if (obj == null || obj.getClass() != getClass()) {
return false;
}
Code language: Java (java)
Third, compare the ssn
and name
fields of the object being compared with the current instance and return true if they are equal:
return ssn.equals(other.ssn) && name.equals(other.name);
Code language: Java (java)
Now, if two Person
objects have the same ssn
and name
, they should be equal when you compare them using the equals()
method:
public class App {
public static void main(String[] args) {
var p1 = new Person("212-15-8397", "John Doe");
var p2 = new Person("212-15-8397", "John Doe");
var result = p1.equals(p2);
System.out.println(result); // true
}
}
Code language: Java (java)
3) hashCode()
The hashCode()
method returns a unique integer that represents an object. If two objects are equal, they should have the same hash code.
Therefore, if you override the equals()
method, you should also override the hashcode()
method.
To generate a hash code for a sequence of input values, you can use the static method hash()
of the Objects
class from java.util
package.
Here’s the modified version of the Person
class that includes a hashCode
method:
import java.util.Objects;
class Person {
private String ssn;
private String name;
// Getters and setters (omitted for brevity)
public Person(String ssn, String name) {
this.ssn = ssn;
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || obj.getClass() != getClass()) {
return false;
}
Person other = (Person) obj;
return ssn.equals(other.ssn) && name.equals(other.name);
}
@Override
public int hashCode() {
return Objects.hash(ssn, name);
}
}
Code language: Java (java)
The following displays the hash codes of the p1
and p2
objects:
public class App {
public static void main(String[] args) {
var p1 = new Person("212-15-8397", "John Doe");
var p2 = new Person("212-15-8397", "John Doe");
var result = p1.equals(p2);
System.out.println(result); // true
System.out.println(p1.hashCode());
System.out.println(p2.hashCode());
}
}
Code language: Java (java)
Output:
true
-1693213186
-1693213186
Code language: Java (java)
4) toString()
The toString()
method returns a string representation of an object. The following displays the default string representation of a Person
object:
public class App {
public static void main(String[] args) {
var person = new Person(
"212-15-8397",
"John Doe"
);
System.out.println(person);
}
}
Code language: Java (java)
Output:
Person@9b139dfe
Code language: Java (java)
When we pass the Person
object to the println()
method, it invokes the toString()
method of the Person
object and displays the resulting string on the screen.
As you can see clearly from the output, the default return value of the toString()
is not human-readable.
Usually, you override the toString()
method to provide the human-readable string representation of the object. For example:
import java.util.Objects;
class Person {
private String ssn;
private String name;
// Getters and setters (omitted for brevity)
public Person(String ssn, String name) {
this.ssn = ssn;
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || obj.getClass() != getClass()) {
return false;
}
Person other = (Person) obj;
return ssn.equals(other.ssn) && name.equals(other.name);
}
@Override
public int hashCode() {
return Objects.hash(ssn, name);
}
@Override
public String toString() {
return "Person{" +
"ssn='" + ssn + '\'' +
", name='" + name + '\'' +
'}';
}
}
Code language: Java (java)
In this example, we override the toString() method of the Person
class to display all the field names and values.
If you run the program that displays a Person
object on the screen, you’ll see something like this:
Person{ssn='212-15-8397', name='John Doe'}
Code language: Java (java)
clone() & finalize()
The Object
class also has the following methods:
clone()
: This method creates a shallow copy of an objectfinalize()
: This method performs the cleanup operations.
In practice, you’ll rarely use these methods so we don’t cover them in this tutorial.
Summary
- In Java, every class is a subclass of the
java.lang.Object
class. - The Java
Object
class provides a number of useful methods for overriding in the subclass includingequals()
,hashCode()
, andtoString()
. - Override
equals()
andhashCode()
to provide logic for comparing two objects by their contents. - Override
toString()
method to provide a meaningful string representation of an object. - Use the
getClass()
method to check the object’s type at runtime.