Проблемы с чтением из хранилища

#codenameone

#codenameone

Вопрос:

Теперь я более глубоко изучил систему хранения, но я просто не могу заставить ее работать должным образом. Данные, похоже, сохранены, сохраненные данные определенно не пусты, и я все еще получаю java.lang.Исключение NullPointerException.

Итак, вот мой класс, который я хочу сохранить и позже прочитать в хранилище.

Band — это тривиальный класс со строкой имени и жанра.

 public class Band implements Externalizable{
    String name;
    String genre;

    public Band(String bnd, String gen){
        this.name = bnd;
        this.genre = gen;
    }
    public Band() {

    }

    public String getName(){
        return this.name;
    }
    public String getGenre() { return this.genre; }
    public void setName(String name) {
        this.name = name;
    }
    public void setGenre(String genre) {
        this.genre = genre;
    }

    @Override
    public String toString(){
        String s;
        s = this.name;
        return s;
    }
    public int getVersion(){
        return 1;
    }

    @Override
    public void externalize(DataOutputStream out) throws IOException {
        Util.writeUTF(name, out);
        Util.writeUTF(genre, out);
    }

    @Override
    public void internalize(int version, DataInputStream in) throws IOException {
        name = Util.readUTF(in);
        genre = Util.readUTF(in);
    }

    public String getObjectId(){
        return "Band";
    }

}
  

BandList — это просто класс с ArrayList, в который добавляются бэнды.

 public class BandList implements Externalizable{
    List <Band> bandList;

    public List getBandList(){
        return this.bandList;
    }

    public BandList(){
        bandList = new ArrayList<Band>();
    }

    public void setBandList(List<Band> bandList) {
        this.bandList = bandList;
    }

    public int getVersion(){
        return 1;
    }

    @Override
    public void externalize(DataOutputStream out) throws IOException {
        Util.writeObject(bandList, out);
    }

    @Override
    public void internalize(int version, DataInputStream in) throws IOException {
        bandList = (ArrayList<Band>) Util.readObject(in);
    }

    public String getObjectId(){
        return "BandList";
    }
}
  

Итак, в каком-то другом классе, где пользователь заполнил некоторые текстовые поля, группа добавляется в список групп, и поэтому я вызываю saveListsToStorage();

 public void saveListsToStorage(){
        Storage.getInstance().clearStorage();
        Storage.getInstance().writeObject("Bands", bandList);
    }
  

Итак, теперь при запуске приложения приложение ищет данные в хранилище, если они найдены, оно вернет сохраненный объект BandList, в противном случае оно вернет новый объект BandList.

До этого я регистрировал классы с

     Util.register("Band", Band.class);
    Util.register("BandList", BandList.class);
  

и, наконец, вызовите этот метод в main в начале:

 public BandList loadSavedBandList() {
        String[] temp = Storage.getInstance().listEntries();
        for (String s : temp) {
            if (s.equals("Bands") == true) {
                BandList tempBand = (BandList) Storage.getInstance().readObject("Bands");
                return tempBand;
            }
        }
        return new BandList();
    }
  

После сохранения и последующей загрузки он выдает исключение NullPointer, и я понятия не имею, почему. Теперь я использовал ArrayList вместо LinkedList, как сказал мне Шай, и я реализовал Externalizable интерфейс, как сказано в руководстве.

Может быть, кто-нибудь из вас может сказать мне, что здесь не так.

Редактировать:

Вот исключение:

 java.lang.NullPointerException
    at com.rosscode.gehma.Menu_Form.updateBandContainer(Menu_Form.java:95)
    at com.rosscode.gehma.Menu_Form.<init>(Menu_Form.java:73)
    at com.rosscode.gehma.main.start(main.java:61)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.codename1.impl.javase.Executor$1$1.run(Executor.java:106)
    at com.codename1.ui.Display.processSerialCalls(Display.java:1152)
    at com.codename1.ui.Display.mainEDTLoop(Display.java:969)
    at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
    at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
  

Правка 2, строка 95:

 if(bandList.getBandList().isEmpty() == false) {
            for (int i = 0; i < bandList.getBandList().size(); i  ) {
                Button temp = new Button(bandList.getBandList().get(i).toString());
                temp.addActionListener((e) ->
                        nextStep()
                );
                listCont.add(temp);
            }
            menuForm.revalidate();
        }
  

Комментарии:

1. Вы включили все, кроме стека NullPointerExcepiton из консоли. Не могли бы вы, пожалуйста, отредактировать свой пост и включить это, а затем оставить комментарий здесь, чтобы я увидел, что вы внесли изменения?

2. Привет, я добавил стек исключений. В методе updateBandContainer() он обновляет BandsContainer путем итерации по списку диапазонов и добавления каждого диапазона в виде кнопки.

3. Итак, что это за код и конкретно строка 95?

4. Добавлено «для» в строке к сообщению. Спасибо за вашу помощь.

5. Вы опубликовали несколько строк, что означает «для»? Вы не можете ссылаться на цикл for, поскольку он ссылается на переменные, используемые одной строкой выше. Вы пробовали запускать это с помощью отладчика, чтобы проверить, какая из ваших переменных равна null?

Ответ №1:

Исключения NullPointerExceptions — довольно удивительные вещи, потому что их не только легко вычислить, они даже показывают вам точную строку, где они происходят. Все, что вам нужно сделать, это посмотреть на все, что осталось от . и проверить, равно ли это null. Как только вы найдете его, вы обнаружите проблему.

Итак, давайте посмотрим на ваш код. К сожалению, я не знаю, какая из этих строк является строкой 95, но я предполагаю, что она начинается с if .

Это означает, что либо bandList равно null, либо bandList.getBandList() возвращает null. Быстрый просмотр getBandList() показывает, что оно не будет равно null, поскольку вы инициализируете список в конструкторе вашего класса BandList. Который оставляет только bandList .

К сожалению, вы не опубликовали, откуда вы это взяли, но я предполагаю, что вы просто сделали что-то вроде:

 BandList bandList = loadSavedBandList();
  

Итак, давайте рассмотрим этот метод. (кстати: я говорю немного больше о том, где вам нужно искать, если вы не сделали этого в конце этого ответа).

Если вы не смогли найти свой ключ, он вернул бы новый список каналов, который не мог быть нулевым. Таким образом, он должен что-то найти, что означает, что ключ существует, но значение равно null.

Итак, давайте сделаем еще один шаг и посмотрим, как вы сохраняете данные в первую очередь.

 public void saveListsToStorage(){
    Storage.getInstance().clearStorage();
    Storage.getInstance().writeObject("Bands", bandList);
}
  

Теперь «в каком-то другом классе» на самом деле мало что объясняет. Но поскольку вы читаете значение null, это означает, что вы записываете здесь значение null. Что означало бы в этом «другом классе», по крайней мере в этом методе, bandList = null .

С приведенным вами кодом я не могу глубже разобраться в этой проблеме, но, похоже, в «том другом классе» вы получили атрибут класса с именем bandList, но не смогли ничего поместить в него.


Или, может быть, вы сохранили все правильно, но не вызывали

 BandList bandList = loadSavedBandList();
  

в той или иной форме перед вашим if , что также в значительной степени объясняет проблему. Я имею в виду … если вы никогда не загрузите список групп, он, очевидно, будет равен null…