Creating and Calling Objects
Learn how to create Java objects, read fields, call instance methods, and understand when two variables refer to the same object.
In Introduction to Methods, we called methods on a Player object. Let’s take a closer look at how we create an object, read its data, and ask it to do something. We’ll use Java’s existing Point class so we can focus on using objects before writing our own classes.
Creating an object
A class defines a type of object: the data it can hold and the behaviour it provides. An object is a particular instance of that class. For example, we can create several points, each representing a different location.
import java.awt.Point;
public class ObjectsDemo {
public static void main(String[] args) {
Point userLocation = new Point(10, 20);
System.out.println(userLocation.y); // 20
}
}
Save this as ObjectsDemo.java, compile it with javac ObjectsDemo.java, and run it with java ObjectsDemo. The import lets us use the short name Point instead of java.awt.Point. Put the following snippets inside main, after the existing lines, unless stated otherwise.
In Point userLocation = new Point(10, 20);, Point is the variable’s type and userLocation is its name. The new expression creates an object, calling the constructor with 10 and 20 to initialise it. The variable stores a reference to that object.
A constructor has the same name as its class and no return type. Here, the arguments supply the initial coordinates. Each time we evaluate new Point(...), we create a separate point.
Reading fields and calling methods
The expression userLocation.y reads a field. It is not a method call. Fields hold data; methods perform operations. A method call includes parentheses, even when there are no arguments:
System.out.println(userLocation.y); // 20
System.out.println(userLocation.getY()); // 20.0
Both lines read the y coordinate. The field has type int, while getY() returns a double. The Point documentation lists its fields, constructors, and methods separately, which is useful when exploring an unfamiliar class.
Changing an object
Point exposes public coordinate fields, so we can change one directly:
userLocation.x = userLocation.x + 2;
System.out.println(userLocation.x); // 12
We can also call an instance method to move the point:
userLocation.translate(3, 0);
System.out.println(userLocation.x); // 15
System.out.println(userLocation.y); // 20
These snippets run in sequence: x starts at 10, becomes 12, then becomes 15. translate(3, 0) adds 3 to x and 0 to y. It changes the existing object and returns void, so there is no result to assign to a variable.
Static and instance methods
An instance method runs on a particular object. In the next example, userLocation is the object receiving the call, and destination is the argument:
Point destination = new Point(18, 24);
double distance = userLocation.distance(destination);
System.out.println(distance); // 5.0
This call calculates the distance without moving either point. An instance method runs on a particular object; a static method belongs to a class and needs no current instance. For a refresher, see Introduction to Methods.
A static field can refer to an object
We’ve already used an instance method throughout this article: println(). Let’s break down a familiar line:
System.out.println("Hello, world!");
System is a class. Its public out field is static, so we access it through the class name without creating a System object. Unlike Point.x and Point.y, which each point has its own copy of, a static field belongs to the class.
The value in out is a reference to a PrintStream object: Java’s standard output stream, usually connected to the console. println("Hello, world!") calls an instance method on that object, printing the text followed by a line separator. The first dot accesses a field; the second calls a method on the object that field refers to.
We can make those two steps visible by storing the reference in a local variable:
java.io.PrintStream output = System.out;
output.println("Hello, world!");
This uses the existing stream; it does not create another one. A static field can hold an object reference, and we can call instance methods on that object. The field being static does not make the object’s methods static. You can check the declarations in the documentation for System.out and PrintStream.println(String).
Two variables can refer to the same object
Assigning an object variable to another variable copies the reference. It does not copy the object:
Point sameLocation = userLocation;
sameLocation.translate(1, 0);
System.out.println(userLocation.x); // 16
Point savedLocation = new Point(userLocation);
savedLocation.translate(10, 0);
System.out.println(savedLocation.x); // 26
System.out.println(userLocation.x); // Still 16
sameLocation and userLocation refer to one point, so either variable lets us change it. The Point constructor used for savedLocation creates a separate point with the same coordinates. Later changes to that copy leave the original alone.
A getter does not make an object read-only
A getter is a method that reads a value, such as getY(). Its presence does not prevent changes: this point still has public fields and methods such as translate.
When writing our own classes, we can make fields private and expose only the operations callers need. In the previous article, Player kept its score private, let callers read it through getScore(), and change it through addBonus(). That controls how the value changes; it does not make the player immutable.
For practice, create two separate points at (0, 0) and (3, 4). Print their distance, then move the first point using translate and calculate it again. Before running the code, predict which coordinates will change. That is the key question behind an instance method call: which object are we working with?