Почему статические классы ломают моего робота?
Я сделал статический класс ниже, чтобы любой класс мог получить доступ к любому из сенсорных методов моего робота 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);
}