java null pointer exception with static array

2019-08-09 08:33发布

I got a null pointer exception when accessing a static array from a static member method. The exception is thrown when i call setData(x, y, z) from a thread. When I debugged it I found out data[0] is null when i try to write to it. I just don't understand how it can be null

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

and

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;

}

5条回答
Summer. ? 凉城
2楼-- · 2019-08-09 09:10

The statement private static regularDataElement[] data = new regularDataElement[nrOfDataElements]; initializes data with an array the size of nrOfDataElements. It does not initialize each element in this array. I.e., all the elements are null.

If you wish to initialize the elements, you should do so yourself. E.g., you could add a static block to handle this:

static regularDataElement[] data = new regularDataElement[nrOfDataElements];
static {
    for (int i = 0; i < nrOfDataElements; ++i) {
        data[i] = new regularDataElement();
    }
}
查看更多
3楼-- · 2019-08-09 09:15

You don't appear to be allocating memory for data[i], which is why you're getting the NPE.

Allocating memory for the array itself is not enough. You need to allocate memory for each element:

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

(Replace ... with the actual arguments.)

查看更多
Emotional °昔
4楼-- · 2019-08-09 09:21

Did you ever initialize the data array?

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

will create an array full of null objects of size nrOfDataElements. It won't actually initialize any elements in the array.

查看更多
我只想做你的唯一
5楼-- · 2019-08-09 09:21

When you initialize an Object array in Java, like data in your code, all elements are by default set to null.

So, you need to populate the data array first, before being able to call any methods against its elements.

Assuming that the regularDataElement class has a no-args (i.e., no parameters) constructor, you could do

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

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

Of course, you could have a separate method to initialize the array, e.g.

static regularDataElement[] initialize(int nrOfDataElements)
{
    regularDataElement[] elements = new regularDataElement[nrOfDataElements];

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

    return elements;
}

and then call that method to create and initialize the data array, replacing the statement

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

with

static regularDataElement[] data = initialize(nrOfDataElements);

Also, as a matter of following established coding conventions, you should name your classes starting with a capital letter, i.e. use RegularDataElement instead of regularDataElement.

查看更多
Fickle 薄情
6楼-- · 2019-08-09 09:24

You never actually create any objects. You must add somewhere:

for (int i = 0; i < data.length; i++) {
    data[i] = new regularDataElement();
}
查看更多
登录 后发表回答