Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Конструкторы

Заполнять поля по одному после new неудобно, и легко что-то забыть. Конструктор решает эту задачу: он получает данные и готовит объект сразу при создании.

Первый конструктор

Конструктор — это особый метод, который вызывается оператором new. Его имя совпадает с именем класса, а тип результата не указывается:

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

Результат:

Анна

Аргументы в скобках после new User передаются в параметры конструктора.

Ключевое слово this

Параметр конструктора удобно называть так же, как поле. Тогда имя name внутри конструктора означает параметр, а к полю обращаются через this — ссылку на текущий объект:

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

Результат:

Олег, 30

Несколько конструкторов

В классе может быть несколько конструкторов с разными параметрами — это та же перегрузка, что и у обычных методов. Java выбирает конструктор по аргументам:

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("Книга", 12.5);
    Product gift = new Product("Открытка");
    IO.println(book.title + ": " + book.price);
    IO.println(gift.title + ": " + gift.price);
}

Результат:

Книга: 12.5
Открытка: 0.0

Вызов this(...) передаёт работу другому конструктору того же класса, поэтому код присваивания полей не повторяется.

Конструктор по умолчанию

Если в классе нет ни одного конструктора, Java сама добавляет пустой конструктор без параметров. Именно поэтому в прошлом уроке работало new User():

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

Результат:

1

Проверка в конструкторе

Конструктор — хорошее место, чтобы не допустить неверных данных. Если значение не подходит, можно выбросить исключение, и объект не будет создан:

class Account {
    double balance;
 
    Account(double balance) {
        if (balance < 0) {
            throw new IllegalArgumentException("Баланс не может быть отрицательным");
        }
        this.balance = balance;
    }
}
 
void main() {
    Account account = new Account(100);
    IO.println(account.balance);
    new Account(-5);
}

Результат:

100.0
Exception in thread "main" java.lang.IllegalArgumentException: Баланс не может быть отрицательным

Подробнее об исключениях — в главе об ошибках.

Частая ошибка

Как только в классе появился хотя бы один свой конструктор, пустой конструктор по умолчанию больше не добавляется. Вызов без аргументов перестаёт компилироваться:

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

Результат:

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 — полное имя класса: в файле Main.java все объявленные классы оказываются внутри неявного класса Main.

Если нужен и такой вызов, объявите конструктор без параметров явно.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.