Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Constructors

Filling fields one by one after new is inconvenient, and it is easy to forget something. A constructor solves this: it receives the data and prepares the object right when it is created.

The first constructor

A constructor is a special method that is called by the new operator. Its name matches the class name, and no return type is written:

class User {
    String name;
 
    User(String n) {
        name = n;
    }
}
 
void main() {
    User user = new User("Anna");
    IO.println(user.name);
}

Output:

Anna

The arguments in parentheses after new User are passed to the constructor's parameters.

The this keyword

It is convenient to give a constructor parameter the same name as the field. Then the name name inside the constructor means the parameter, and the field is reached through this — a reference to the current object:

class User {
    String name;
    int age;
 
    User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
 
void main() {
    User user = new User("Oleg", 30);
    IO.println(user.name + ", " + user.age);
}

Output:

Oleg, 30

Several constructors

A class may have several constructors with different parameters — the same overloading that ordinary methods have. Java picks a constructor by its arguments:

class Product {
    String title;
    double price;
 
    Product(String title, double price) {
        this.title = title;
        this.price = price;
    }
 
    Product(String title) {
        this(title, 0.0);
    }
}
 
void main() {
    Product book = new Product("Book", 12.5);
    Product gift = new Product("Postcard");
    IO.println(book.title + ": " + book.price);
    IO.println(gift.title + ": " + gift.price);
}

Output:

Book: 12.5
Postcard: 0.0

The this(...) call hands the work over to another constructor of the same class, so the code that assigns fields is not repeated.

The default constructor

If a class has no constructors at all, Java adds an empty constructor without parameters by itself. That is why new User() worked in the previous lesson:

class Counter {
    int value;
}
 
void main() {
    Counter counter = new Counter();
    counter.value++;
    IO.println(counter.value);
}

Output:

1

Validation in the constructor

A constructor is a good place to keep wrong data out. If a value does not fit, you can throw an exception, and the object will not be created:

class Account {
    double balance;
 
    Account(double balance) {
        if (balance < 0) {
            throw new IllegalArgumentException("Balance cannot be negative");
        }
        this.balance = balance;
    }
}
 
void main() {
    Account account = new Account(100);
    IO.println(account.balance);
    new Account(-5);
}

Output:

100.0
Exception in thread "main" java.lang.IllegalArgumentException: Balance cannot be negative

Exceptions are covered in detail in the chapter on errors.

Common mistake

As soon as a class has at least one constructor of its own, the empty default constructor is no longer added. A call without arguments stops compiling:

class User {
    String name;
 
    User(String name) {
        this.name = name;
    }
}
 
void main() {
    User user = new User();
}

Output:

Main.java:10: error: constructor User in class Main.User cannot be applied to given types;
    User user = new User();
                ^
  required: String
  found:    no arguments
  reason: actual and formal argument lists differ in length

Main.User is the full name of the class: in the file Main.java all declared classes end up inside the implicit class Main. If you need that call too, declare a constructor without parameters explicitly.

Thanks for reading!

Donate to the site — we work hard for you.