Исключение нулевого указателя Java со статическим массивом
Я получил исключение нулевого указателя при доступе к статическому массиву из метода статического члена. Исключение выдается, когда я вызываю setData(x, y, z) из потока. Когда я отладил его, я обнаружил, что данные [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;
}
5 ответов
Заявление private static regularDataElement[] data = new regularDataElement[nrOfDataElements];
инициализирует data
с массивом размером nrOfDataElements
, Он не инициализирует каждый элемент в этом массиве. Т.е. все элементы равны нулю.
Если вы хотите инициализировать элементы, вы должны сделать это самостоятельно. Например, вы можете добавить статический блок для обработки этого:
static regularDataElement[] data = new regularDataElement[nrOfDataElements];
static {
for (int i = 0; i < nrOfDataElements; ++i) {
data[i] = new regularDataElement();
}
}
Вы когда-нибудь инициализировали data
массив?
private static regularDataElement[] data =
new regularDataElement[nrOfDataElements];
создаст массив, полный null
объекты размером nrOfDataElements
, На самом деле он не будет инициализировать какие-либо элементы в массиве.
Вы, кажется, не выделяете память для data[i]
Вот почему вы получаете NPE.
Выделение памяти для самого массива недостаточно. Вам необходимо выделить память для каждого элемента:
for (int i = 0; i < nrOfDataElements; ++i) {
data[i] = new regularDataElement(...);
}
(Заменить ...
с фактическими аргументами.)
Вы никогда не создаете никаких объектов. Вы должны добавить куда-нибудь:
for (int i = 0; i < data.length; i++) {
data[i] = new regularDataElement();
}
Когда вы инициализируете Object
массив в Java
, лайк 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
,