【问题标题】:Why do static classes crash my robot?为什么静态类会使我的机器人崩溃?
【发布时间】:2011-10-25 06:02:22
【问题描述】:

我在下面创建了静态类,因此任何类都可以访问我的 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);
    }
}

【问题讨论】:

  • 因为 motorAnull 直到你调用构造函数。您不应该在实例构造函数中分配静态变量
  • 能否请您提供一下在这种情况下崩溃意味着什么,您是否遇到异常或虚拟机崩溃?
  • 这不是一个静态类。这是一个包含大量静态数据和方法的类。

标签: java static static-methods lego lejos-nxj


【解决方案1】:

您正在尝试创建一个实用程序类,但您的变量初始化发生在构造函数中。

构造函数仅在实例被构造时被调用(通过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.
}

【讨论】:

    【解决方案2】:

    因为当您不调用构造函数 StandardRobot 时,您并没有实例化电机 A、电机 B、超声波传感器等,因此它们默认为 null,从而在运行时导致 NullPointerExceptions。您可以将所有这些字段设为实例变量,也可以考虑使用静态初始化块,即

       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);
    }
    

    【讨论】:

      【解决方案3】:

      静态变量是为类定义的,而不是为实例定义的。您定义的构造函数是为实例调用的,而不是类。结果你的变量可能没有被初始化。

      在相关节点上:使变量静态化的想法不是很好。您将自己限制为只有一个机器人,因为所有机器人都会共享状态。

      【讨论】:

        【解决方案4】:

        用静态部分替换你的构造函数:

        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);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-10-12
          • 2018-09-09
          • 2016-09-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-01-11
          相关资源
          最近更新 更多