【问题标题】:java null pointer exception with static array带有静态数组的java空指针异常
【发布时间】:2013-12-02 04:06:49
【问题描述】:

从静态成员方法访问静态数组时出现空指针异常。 当我从线程调用 setData(x, y, z) 时引发异常。当我调试它时,当我尝试写入它时,我发现 data[0] 为空。我只是不明白它怎么会是空的

public class dataContainer 
{
    private static final short nrOfDataElements = ids.total_ids;
    private static regularDataElement[] data = new regularDataElement[nrOfDataElements];


    public static synchronized void getData(final short i, regularDataElement r)
    {
        if ( (i >= 0) && (i < nrOfDataElements) )
            r.set(data[i].getTimestamp(), data[i].getValue());  
    }          

    public static synchronized void setData(short i, double ts, long val)
    {
        if ( (i >= 0) && (i < nrOfDataElements) )
            data[i].set(ts, val); //<<-------null pointer exception, debugging showed data[i] == null, (with i = 0 and nrOfDataElements = 12)
    }
}

public class regularDataElement 
{
    regularDataElement()
    {
        set(0, 0);
    }

    public void set(double _ts, long _val)
    {
        System.out.println(this.ts + " " + _ts + " " + this.val + " " + _val); System.out.flush();
        this.ts = _ts;
        this.val = _val;    
    }

    public double getTimestamp()
    {
        return this.ts;
    }

    public long getValue()
    {
        return this.val;
    }

    private double ts;
    private long val;

}

【问题讨论】:

    标签: java static static-methods static-members static-array


    【解决方案1】:

    您似乎没有为 data[i] 分配内存,这就是您获得 NPE 的原因。

    为数组本身分配内存是不够的。您需要为每个元素分配内存:

    for (int i = 0; i < nrOfDataElements; ++i) {
       data[i] = new regularDataElement(...);
    }
    

    (将... 替换为实际参数。)

    【讨论】:

      【解决方案2】:

      你有没有初始化过data 数组?

      private static regularDataElement[] data = 
          new regularDataElement[nrOfDataElements];
      

      将创建一个包含null 大小为nrOfDataElements 的对象的数组。它实际上不会初始化数组中的任何元素。

      【讨论】:

        【解决方案3】:

        您实际上从未创建任何对象。您必须在某处添加:

        for (int i = 0; i < data.length; i++) {
            data[i] = new regularDataElement();
        }
        

        【讨论】:

          【解决方案4】:

          当您在Java 中初始化Object 数组时,例如代码中的data,所有元素默认设置为null

          因此,您需要先填充 data 数组,然后才能针对其元素调用任何方法。

          假设regularDataElement 类有一个无参数(即无参数)构造函数,您可以这样做

          static regularDataElement[] data = new regularDataElement[nrOfDataElements];
          
          static
          {
              for (int i=0; i<nrOfDataElements; i++)
              {
                  data[i] = new regularDataElement();
              }
          }
          

          当然,你可以有一个单独的方法来初始化数组,例如

          static regularDataElement[] initialize(int nrOfDataElements)
          {
              regularDataElement[] elements = new regularDataElement[nrOfDataElements];
          
              for (int i=0; i<nrOfDataElements; i++)
              {
                  elements[i] = new regularDataElement();
              }
          
              return elements;
          }
          

          然后调用该方法创建并初始化数据数组,替换语句

          static regularDataElement[] data = new regularDataElement[nrOfDataElements];
          

          static regularDataElement[] data = initialize(nrOfDataElements);
          

          此外,为了遵循既定的编码约定,您应该以大写字母开头命名您的类,即使用RegularDataElement 而不是regularDataElement

          【讨论】:

            【解决方案5】:

            语句private static regularDataElement[] data = new regularDataElement[nrOfDataElements];nrOfDataElements 大小的数组初始化data。它初始化这个数组中的每个元素。即,所有元素都是空的。

            如果你想初始化元素,你应该自己做。例如,您可以添加一个静态块来处理此问题:

            static regularDataElement[] data = new regularDataElement[nrOfDataElements];
            static {
                for (int i = 0; i < nrOfDataElements; ++i) {
                    data[i] = new regularDataElement();
                }
            }
            

            【讨论】:

            • 谢谢,这完全成功了。我假设数组元素的内存将被隐式分配,就像在 c++ 中一样。静态范围很棒,不知道这是可能的,谢谢 :-)
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-17
            • 1970-01-01
            相关资源
            最近更新 更多