Skip to content
Theory · Classes and objects · lesson 1 of 10

Class and object

What you'll learn

What you'll learn:

  • describe your own type with a class, create objects with new and explain why two variables can lead to one object;
  • set an object's fields in a constructor and tell this.x from x inside it;
  • close fields with private and tell an object's field from a static field;
  • print an object through toString and read a NullPointerException message.

Picture the blueprint of a house. It says what every house will have: how many floors, what color the roof is. You cannot live in a blueprint; it is only a description. But one blueprint can give you a whole street. The houses come out alike, yet each has its own roof, and repainting one house leaves its neighbor as it was.

Java works the same way. The blueprint is a class: it describes the data every object will have. A house is an object, which the program builds from the blueprint while it runs.

Why do we need this? Take a point on a plane. It is two numbers, x and y, and they always go together. A hundred points would need two hundred variables, and the x of one point would sit next to the y of another. A class lets you tell Java "a point is a pair of numbers" and then work with a point as one thing:

JAVA
public class Main {
    public static void main(String[] args) {
        Point p = new Point();
        p.x = 3;
        p.y = 4;
        System.out.println(p.x + " " + p.y); // 3 4
        Point q = new Point();
        System.out.println(q.x + " " + q.y); // 0 0
    }
}

class Point {
    int x;
    int y;
}

Let's go through the program step by step:

  1. At the bottom of the file, the class Point is declared with two fields, x and y. This is the blueprint.
  2. new Point() builds an object from the blueprint, one point, and Point p declares a variable for it.
  3. p.x = 3; and p.y = 4; put numbers into the fields of this point. The dot between the variable name and the field name reads as "the field x of the point p leads to".
  4. The first println prints 3 4.
  5. new Point() builds a second point. Nobody put anything into its fields, so it prints 0 0.

What a class describes

A class is the description of a new type: which fields each of its objects will have. Once class Point is declared, the program has a type Point, and you declare a variable of this type the same way as a variable of type int or String.

An object is one concrete thing built from a class with new. An object is also called an instance of the class. What matters about objects:

  • each object has its own fields: writing to p.x does not change q.x;
  • the fields of a new object get default values, like static fields: 0 for numbers, false for boolean, null for String;
  • you can create as many objects of one class as you like, and each new builds a new one.

The class Point is declared in the same file, after Main, and without the word public. A file may hold only one public class, and the file is named after it: Main.java.

A variable holds an address

Back to the street. The variable p holds not the house itself but a slip of paper with its address. As with an array, this is a reference: new Point() builds the object on the heap and returns a reference to it. Let's see what happens when you copy such a slip:

JAVA
Point a = new Point();
Point b = a;
b.x = 7;
System.out.println(a.x); // 7

Line by line:

  1. Point a = new Point(); builds a house and puts its address into a.
  2. Point b = a; copies the slip with the address, not the house. Now a and b lead to one object.
  3. b.x = 7; follows the address in b and changes a field of that object.
  4. a.x prints 7: the address in a leads to the same house.

If you now write b = new Point();, the slip b gets the address of a new house. The old house is not affected: a still leads to it, and a.x stays 7.

Here the house picture is not exact. You can reach a real house without a slip if you know the street. A program reaches an object only through a reference: if no variable leads to an object, there is no way to work with it anymore.

An object as a method parameter

Interviewers like to ask this: can a method change an object passed to it? Let's see:

JAVA
public class Main {
    static void move(Point p) {
        p.x = 10;
        p = new Point();
        p.x = 20;
    }

    public static void main(String[] args) {
        Point a = new Point();
        move(a);
        System.out.println(a.x); // 10
    }
}

class Point { int x; int y; }

The class Point here is the same, only written on one line. Let's go through the call move(a) step by step:

  1. The parameter p gets a copy of the value of a, that is, a copy of the address. Now a and p lead to one point.
  2. p.x = 10; changes a field of that point, and main will see the change.
  3. p = new Point(); writes the address of a new point on the slip p. The slip a in main stays as it was.
  4. p.x = 20; changes the new point, which main knows nothing about.
  5. main prints 10.

The interview answer goes like this: Java always passes arguments by value, and the value of an object variable is a reference. So a method can change an object's fields, but it cannot make the caller's variable lead to another object.

Common mistake

The variable is declared, but the object is never built:

JAVA
Point p;
p.x = 3; // ✗
TEXT
error: variable p might not have been initialized

The program does not compile. Point p; declares only the slip for an address; nobody built a house, so there is nowhere to put 3. Only new creates an object: Point p = new Point();.

Key points

  • A class describes the fields of a new type, and new builds an object from it; each object has its own fields.
  • A variable of type Point holds a reference to an object, so Point b = a copies the reference, and a and b lead to one object.
  • A method gets a copy of the reference: it can change the object's fields, but assigning to the parameter does not change the caller's variable.
  • Without new there is no object: Point p; does not create a point.