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

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

Имя конструктора совпадает с именем класса, а тип возвращаемого значения не указывается — даже void. Если в классе не объявлен ни один конструктор, компилятор автоматически добавит конструктор по умолчанию без параметров.

Конструкторов в классе может быть несколько — они различаются по числу и типам параметров (перегрузка). Один конструктор может вызвать другой через this(...) — это удобно, чтобы не дублировать код инициализации.

Синтаксис

public class ИмяКласса {
    // поля
    тип поле;

    public ИмяКласса() { ... }                 // без параметров
    public ИмяКласса(тип1 a, тип2 b) { ... }   // параметризованный
}

Пример 1. Конструктор по умолчанию

public class Led {
    int pin;
    boolean isOn;

    public Led() {
        pin = 13;
        isOn = false;
        System.out.println("Создан Led по умолчанию");
    }

    public static void main(String[] args) {
        Led led = new Led();
        System.out.println("pin=" + led.pin + " isOn=" + led.isOn);
    }
}

Output:

Создан Led по умолчанию
pin=13 isOn=false

Пример 2. Параметризованный конструктор

public class Motor {
    String name;
    int pinEna;
    int speed;

    public Motor(String name, int pinEna) {
        this.name = name;
        this.pinEna = pinEna;
        this.speed = 0;
    }

    public static void main(String[] args) {
        Motor left = new Motor("Левый", 6);
        Motor right = new Motor("Правый", 5);
        System.out.println(left.name + " на пине " + left.pinEna);
        System.out.println(right.name + " на пине " + right.pinEna);
    }
}

Output:

Левый на пине 6
Правый на пине 5

Пример 3. Перегрузка конструкторов

public class Sensor {
    String type;
    int pin;

    public Sensor() {
        this.type = "generic";
        this.pin = -1;
    }

    public Sensor(String type) {
        this.type = type;
        this.pin = -1;
    }

    public Sensor(String type, int pin) {
        this.type = type;
        this.pin = pin;
    }

    public static void main(String[] args) {
        Sensor a = new Sensor();
        Sensor b = new Sensor("DHT22");
        Sensor c = new Sensor("BH1750", 14);
        System.out.println(a.type + "/" + a.pin);
        System.out.println(b.type + "/" + b.pin);
        System.out.println(c.type + "/" + c.pin);
    }
}

Output:

generic/-1
DHT22/-1
BH1750/14

Пример 4. Вызов одного конструктора из другого через this()

public class Robot {
    String name;
    int wheels;
    int battery;

    public Robot() {
        this("NoName", 4, 100);
    }

    public Robot(String name) {
        this(name, 4, 100);
    }

    public Robot(String name, int wheels, int battery) {
        this.name = name;
        this.wheels = wheels;
        this.battery = battery;
    }

    public static void main(String[] args) {
        Robot a = new Robot();
        Robot b = new Robot("Phobo");
        Robot c = new Robot("Tank", 6, 80);
        System.out.println(a.name + " w=" + a.wheels + " b=" + a.battery);
        System.out.println(b.name + " w=" + b.wheels + " b=" + b.battery);
        System.out.println(c.name + " w=" + c.wheels + " b=" + c.battery);
    }
}

Output:

NoName w=4 b=100
Phobo w=4 b=100
Tank w=6 b=80

Пример 5. Валидация значений в конструкторе

public class Servo {
    int pin;
    int angle;

    public Servo(int pin, int angle) {
        if (angle < 0) angle = 0;
        if (angle > 180) angle = 180;
        this.pin = pin;
        this.angle = angle;
    }

    public static void main(String[] args) {
        Servo a = new Servo(9, 250);
        Servo b = new Servo(9, -30);
        Servo c = new Servo(9, 90);
        System.out.println("a.angle=" + a.angle);
        System.out.println("b.angle=" + b.angle);
        System.out.println("c.angle=" + c.angle);
    }
}

Output:

a.angle=180
b.angle=0
c.angle=90

Подводные камни

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

  • Конструктор не имеет типа возвращаемого значения. Если написать void, это уже метод, а не конструктор.

  • Вызов this(...) должен быть первой строкой в теле конструктора.

  • this.pin = pin; — типичная конструкция, когда параметр совпадает по имени с полем; без this поле не будет проинициализировано.

  • Не выполняйте тяжёлые операции (сеть, файлы) в конструкторе — объект может остаться в полусоздан­ном состоянии при исключении.

См. также

Примечание

Лицензия и источники

Концепция описана на основе официального Java Tutorial от Oracle (https://docs.oracle.com/javase/tutorial/), Oracle Free Documentation License. Перевод, примеры и пояснения — © AlashEd Wiki.