Почему статические классы ломают моего робота?

Я сделал статический класс ниже, чтобы любой класс мог получить доступ к любому из сенсорных методов моего робота lejos без необходимости создавать экземпляр для каждого класса.

Однако всякий раз, когда я вызываю такой метод, как StandardRobot.motorA.setPower(100) мой робот падает Когда я использую точно такой же класс и делаю его локальный экземпляр, это прекрасно работает. Почему это? Оба раза мой код компилируется нормально и не работает во время выполнения.

import lejos.nxt.*;

public class StandardRobot {

    public static ColorSensor colourSensor;
    public static TouchSensor touchSensor;
    public static UltrasonicSensor ultrasonicSensor;
    public static NXTMotor motorA, motorB;

    public StandardRobot() {
        // instantiate sensors
        ultrasonicSensor = new UltrasonicSensor(SensorPort.S1);
        colourSensor = new ColorSensor(SensorPort.S2);
        touchSensor = new TouchSensor(SensorPort.S4);

        //instantiate motors
        motorA = new NXTMotor(MotorPort.A);
        motorB = new NXTMotor(MotorPort.B);
    }
}

4 ответа

Решение

Вы пытаетесь создать служебный класс, но инициализация вашей переменной происходит в конструкторе.

Конструкторы вызываются только тогда, когда экземпляр... создается (через new).

Вы должны инициализировать статические свойства статически, либо в статическом блоке инициализации, либо в том виде, в котором они объявлены.

// Initialize static properties as they're declared.
public static ColorSensor colourSensor = new ColorSensor(SensorPort.S2);

// Or initialize in a static initialization block to do them all at once.
public static TouchSensor touchSensor;
// ... and the others.
static {
    touchSensor = new TouchSensor(SensorPort.S4);
    // ... and the others.
}

Потому что, когда вы не вызываете конструктор StandardRobot, вы не создаете экземпляры motorA, motorB, ultrasonicSensor и т. Д., Поэтому они по умолчанию имеют значение null, что приводит к исключениям NullPointerException во время выполнения. Вы можете сделать все эти переменные экземпляра полей или рассмотреть возможность использования статического блока инициализации, т.е.

   static {
 // instantiate sensors
    ultrasonicSensor = new UltrasonicSensor(SensorPort.S1);
    colourSensor = new ColorSensor(SensorPort.S2);
    touchSensor = new TouchSensor(SensorPort.S4);

    //instantiate motors
    motorA = new NXTMotor(MotorPort.A);
    motorB = new NXTMotor(MotorPort.B);
}

Статические переменные определены для класса, а не для экземпляра. Определенный вами конструктор вызывается для экземпляра, а не для класса. В результате ваши переменные могут не инициализироваться.

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

Замените ваш конструктор статическим разделом:

static {
        // instantiate sensors
        ultrasonicSensor = new UltrasonicSensor(SensorPort.S1);
        colourSensor = new ColorSensor(SensorPort.S2);
        touchSensor = new TouchSensor(SensorPort.S4);

        //instantiate motors
        motorA = new NXTMotor(MotorPort.A);
        motorB = new NXTMotor(MotorPort.B);
}
Другие вопросы по тегам