2014-10-05 2 views
1

Я тяну свои волосы, пытаясь понять, почему я получаю NullPointerException в этом коде.Почему это бросает исключение NullPointerException?

Вот соответствующие фрагменты кода.

(основной)

... 

    try (RawData setupData = new RawData(
      new File(fileName), log);) { 

     while (true) { 

      record = setupData.nextRecord(); 
      if (record == null) 
       break; 

      System.out.println(record.getCountryCode()); 
      System.out.println(record.getCountryID()); 
      table.put(record); 
      index.put(record); 

      count++; 

     } 


    } catch (IOException e) { 

     e.printStackTrace(); 

    } 

... 

(метод пут)

public void put(DataTableRecord country) { 

    this.current = country; 

    try { 

     this.file.seek(this.current.getCountryID() * RECORD_SIZE); 
     if (!exists(this.current.getCountryID())) { 

      writeExternal(this.current); 
      this.size++; 
      if (country.getCountryID() > this.last) 
       this.last = country.getCountryID(); 

     } 

    } catch (IOException e) { 

     e.printStackTrace(); 

    } 

} 

(метод writeExternal)

private void writeExternal(DataTableRecord data) throws IOException { 

    System.out.println(data.getCountryCode()); 
    this.file.writeUTF(data.getCountryCode()); 
    this.file.writeShort(data.getCountryID()); 
    this.file.writeUTF(data.getName()); 
    switch (data.getContinent()) { 

    case AFRICA : 
     this.file.writeShort(1); 
     break; 

    ... 

    case SOUTH_AMERICA : 
     this.file.writeShort(7); 
     break; 

    } 

    this.file.writeInt(data.getArea()); 
    this.file.writeLong(data.getPopulation()); 
    this.file.writeFloat(data.getLifeExpectancy()); 

} 

Каждый раз, цикл успешно работает в два раза, а на третьей итерации дает мне NullPointerException. Для отладки были вставлены вызовы System.out.writeln. Из вызовов writeln я вижу, что объект, который я передаю методу writeExternal, не является нулевым, прежде чем метод будет вызван. На третьей итерации, я получаю следующее сообщение об ошибке:

Exception in thread "main" java.lang.NullPointerException 
    at edu.wmich.cs3310.jwhite_cotw.DataTable.writeExternal(DataTable.java:255) 
    at edu.wmich.cs3310.jwhite_cotw.DataTable.put(DataTable.java:159) 
    at edu.wmich.cs3310.jwhite_cotw.Setup.main(Setup.java:62) 

Я не могу понять, где null откуда. Как объект может быть нулевым, если он не был null непосредственно перед вызовом метода? У кого-нибудь есть идеи? Я должен упомянуть, что поле «this.file» - это RandomAccessFile, открытый с помощью «rw».

DataTable.java:255 является линия

this.file.writeUTF(data.getCountryCode()); 

DataTable.java:159 является линия

writeExternal(this.current); 

и Setup.java:62 является линия

table.put(record); 

Любые предложения (даже как раз в правильном направлении) были бы наиболее оценены.

+4

Первый шаг - выяснить * точно *, что такое 'null'. В строке 255 это может быть либо 'this.file', либо' data'. Что он? –

+0

Я добавил два условия: один, чтобы отобразить сообщение, если 'this.file' был null, и один, чтобы отобразить сообщение, если' data' было null. Ни одно условие не было вызвано. – aerophage

+1

Да, очевидно, что либо 'data', либо' file' равно null. Либо используйте отладчик для остановки в строке 255 и проверьте их, либо добавьте инструкции println только перед этой строкой, чтобы выполнить 'String.valueOf (data)' и 'String.valueOf (this.file)', чтобы узнать, являются ли они нулевыми. –

ответ

1

Ошибка, когда параметр равен writeExternal: null. Так что утверждение является проблематичным

writeExternal(this.current); 

, если вы измените что

writeExternal(country); 

это может спасти вас от ошибок, но, вероятно, вы должны перестроить свой код для обработки NullPointer исключения или, по крайней мере, объявить его с помощью броска пункта ,

+0

Я не знаю, как это изменило ситуацию, но сразу же устранило исключение. Спасибо огромное! Теперь мне просто нужно войти и выяснить, почему назначение не получилось, но спасибо, что указали мне в правильном направлении! – aerophage

-1

Потому что я экстрасенс, я могу сказать, что проблема ...

COUNTRYCODE поле имеет тип Integer, но параметр тип exists() является int. Это означает, что при передаче countryCode в метод Integer автоматически распаковывается в int, но если countryCode имеет значение null, это действие вызывает NPE.

Измените тип параметра на Integer и убедитесь, что метод обрабатывает значение null.

Отказ от ответственности: у меня могут быть неправильные имена полей и методов, но я вполне уверен в общей причине.

+0

Цикл выполняется правильно дважды перед сбоем на третьей итерации, а countryCode имеет тип 'String'. – aerophage

+0

@aerophage и что? Поле объекта может быть нулевым, если объект не является нулевым. – Bohemian

+0

Я также проверил непосредственно перед тем, как метод был вызван, что countryCode не был нулевым. – aerophage

Смежные вопросы