#java #nullpointerexception #pass-by-reference
#java #исключение nullpointerexception #передача по ссылке
Вопрос:
Я довольно новичок в этом форуме. Я всегда с опаской относился к публикациям на форумах, но после двух недель битья головой о свой код, пытаясь заставить его работать, я, наконец, сдался. Приведенный ниже код является важной частью некоторого большего кода, но я думаю, что я вроде как точно определил проблемный раздел. У меня есть 2D массив объектов, которые должны быть инициализированы по умолчанию, как только он будет создан. Однако, похоже, этого не происходит, и значение остается нулевым. Может ли это быть результатом того, что Java не может передавать по ссылке? Если это так, то почему примитивные 2D-массивы создаются отлично? Заранее благодарю тебя, Ласц.
class ObjectThing
{
int someInt;
double someDouble;
public ObjectThing()
{
someInt = 0;
someDouble = 0;
}
synchronized private void someIntIncrement ()
{
someInt ;
}
synchronized public void addSomeDouble (double sd)
{
someDouble = sd;
someIntIncrement ();
}
synchronized public String toString ()
{
return someInt "," someDouble;
}
}
class AnotherObject
{
String name;
ObjectThing [][] someObjectMAtrix;
double [][] someDoubleMAtrix01;
double [][] someDoubleMAtrix02;
public AnotherObject()
{
}
private void initDouble (double [][] mat)
{
for (double [] i: mat)
for (double j: i)
j = 0;
}
private void initObject (ObjectThing [][] so)
{
for (ObjectThing [] i: so)
for (ObjectThing j: i)
j = new ObjectThing ();
}
public void init (int r, int c)
{
someObjectMAtrix = new ObjectThing [r][c];
someDoubleMAtrix01 = new double [r][c];
someDoubleMAtrix01 = new double [r][c];
initObject (someObjectMAtrix);
initDouble (someDoubleMAtrix01);
initDouble (someDoubleMAtrix02);
}
}
class Driver
{
public static void main (String [] args)
{
initializeMethod();
}
public void initializeMethod ()
{
AnotherObject [] anotherObjectArray = new AnotherObject [1];
for (AnotherObject i: anotherObjectArray)
{
i.init(72,72);
}
}
}
Комментарии:
1. Если вы получили исключение NullPointerException, как следует из названия, полезно, если вы также включите его в свой вопрос.
2. » Может ли это быть результатом того, что Java не может передавать по ссылке?» Нет. Вы делаете это неправильно. Также может предоставить меньшую выборку с воспроизводимой ошибкой?
3. Не могли бы вы также предоставить трассировку стека, пожалуйста?
4. Пожалуйста, пожалуйста, пожалуйста, хотя бы НАМЕКНИТЕ, где в вашем коде возникает исключение нулевого указателя. Java создает очень хорошую трассировку стека исключений, и было бы очень полезно просмотреть несколько верхних строк этого с некоторыми подсказками относительно того, какие строки соответствуют строкам # s в трассировке.
Ответ №1:
Проблема в вашем initializeMethod:
AnotherObject [] anotherObjectArray = new AnotherObject [1];
for (AnotherObject i: anotherObjectArray)
{
i.init(72,72);
}
Переход Object[] myArray = new Object[1]
только выделяет пространство для массива. На самом деле это не создает эти объекты. Ваш блок кода должен быть
AnotherObject [] anotherObjectArray = new AnotherObject [1];
anotherObjectArray[0] = new AnotherObject();
for (AnotherObject i: anotherObjectArray)
{
i.init(72,72);
}
Это немного неуклюже. Я предполагаю, что у вас есть какая-то потребность поместить AnotherObject в массивы, и вы просто не показываете это. Если вам нужен только один из этих объектов, просто создайте его напрямую. Вероятно, вам следует взглянуть на Списки
Ответ №2:
Я считаю, что это сделано специально. Примитив будет выделен в стеке и всегда будет иметь какое-то значение по умолчанию. Объект выделяется в куче и будет передаваться по ссылке. Эти ссылки по умолчанию ни на что не будут указывать, пока вы не инициализируете их.
Ответ №3:
Вы только что инициализировали массив объектов AnotherObject…но в первом поле массива нет AnotherObject… Это значение равно нулю, поскольку вы его не инициализировали. В initializeMethod вы должны выполнить следующее:
AnotherObject [] anotherObjectArray = new AnotherObject [1];
for (AnotherObject i: anotherObjectArray)
{
i = new AnotherObject();
i.init(72,72);
}
приветствия!
Ответ №4:
Компилятор Java заставит вас инициализировать переменные, примитивы или ссылочные типы (например, объекты), или он сгенерирует ошибку компилятора и завершится сбоем.
Однако при инициализации массива будет создан массив желаемого размера, для каждого элемента которого установлено значение по умолчанию. Для примитивов это что-то вроде 0
для числовых типов, false
для логических значений. Для ссылочных типов значение по умолчанию равно null
. Это источник вашей проблемы.
Вы правильно инициализируете массив, но не заполняете его допустимыми значениями. Итак, это связано не с передачей по ссылке, а с правильной инициализацией массива и знанием значений по умолчанию для вновь инициализированного массива.
В частности, вы используете конструкцию for-each для перебора массива. Эта конструкция выполняет операцию над каждым объектом в коллекции / массиве.
Следовательно, этот код:
AnotherObject [] anotherObjectArray = new AnotherObject [1];
for (AnotherObject i: anotherObjectArray){
i.init(72,72);
}
эквивалентно этому коду:
AnotherObject [] anotherObjectArray = new AnotherObject [1];
for(int count=0; count < anotherObjectArray ; count ){
AnotherObject tempObj = anotherObjectArray[i]; // This is null, because anotherObjectArray[i] hasn't been initialised yet
tempObj.init(72,72); // This is where we get the NullPointerException :(
}
Вы видите проблему? Вы пытаетесь выполнить операцию над null, следовательно NullPointerException
Я полагаю, что вы на самом деле намеревались сделать это:
AnotherObject [] anotherObjectArray = new AnotherObject [1];
for(int count=0; count < anotherObjectArray ; count ){
AnotherObject tempObj = new AnotherObject(); // Here we create the new object
tempObj.init(72,72); // Initialise the newly created object
anotherObjectArray[i] = tempObj; // Now we store in the array :)
}
Надеюсь, я объяснил это достаточно ясно, но, пожалуйста, попросите разъяснений, если я этого не сделал 🙂
Комментарии:
1. Если мой ответ помог, принятие / голосование за него — хороший способ выразить свою признательность 🙂