Codenameone 从存储器读取数据时出现问题

Codenameone 从存储器读取数据时出现问题,codenameone,Codenameone,我现在对存储系统有了更深入的了解,但我就是不能让它正常工作。数据似乎已经保存,保存的数据肯定不是空的,我仍然得到一个java.lang.NullPointerException 这是我要保存的类,稍后将其读入存储器 Band是一个具有名称和类型字符串的普通类 public class Band implements Externalizable{ String name; String genre; public Band(String bnd, String gen)

我现在对存储系统有了更深入的了解,但我就是不能让它正常工作。数据似乎已经保存,保存的数据肯定不是空的,我仍然得到一个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";
    }
}
现在,当启动应用程序时,应用程序正在存储器中查找数据,如果找到,它将返回存储的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而不是Shai告诉我的LinkedList,并按照指南中的说明实现了可外部化的接口

也许你们中的一些人可以告诉我这里出了什么问题

编辑:

例外情况如下:

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)
java.lang.NullPointerException
在com.rosscode.gehma.Menu\u Form.updateBandContainer(Menu\u Form.java:95)上
在com.rosscode.gehma.Menu\u Form.(Menu\u Form.java:73)
位于com.rosscode.gehma.main.start(main.java:61)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:497)
位于com.codename1.impl.javase.Executor$1$1.run(Executor.java:106)
位于com.codename1.ui.Display.processSerialCalls(Display.java:1152)
位于com.codename1.ui.Display.mainEDTLoop(Display.java:969)
位于com.codename1.ui.runnablerrapper.run(runnablerrapper.java:120)
位于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();
        }
if(bandList.getBandList().isEmpty()==false){
对于(int i=0;i
下一步()
);
列表控制添加(临时);
}
menuForm.revalidate();
}

NullPointerException是非常令人惊奇的事情,因为它们不仅易于识别,甚至可以向您显示它们发生的确切位置。您所要做的就是查看
的剩余部分,并检查它是否为空。一旦你找到它,你就会发现问题所在

让我们看看你的代码。遗憾的是,我不知道其中哪一行是第95行,但我猜是以
if
开头的那一行

这意味着
bandList
为null或
bandList.getBandList()
返回null。快速查看
getBandList()
会发现,当您在BandList类的构造函数中初始化列表时,它不会为null。只剩下
波段列表

遗憾的是,你没有发布你从哪里得到的信息,但我想你只是做了如下事情:

BandList bandList = loadSavedBandList();
让我们来研究一下这个方法。(顺便说一句:如果你在这个答案的末尾没有这样做,我会说更多关于你必须看的地方)

如果找不到密钥,它将返回一个新的带列表,不能为空。所以它必须找到一些东西,这意味着键存在,但值为null

那么,让我们采取另一个步骤,首先看看你是如何保存东西的

public void saveListsToStorage(){
    Storage.getInstance().clearStorage();
    Storage.getInstance().writeObject("Bands", bandList);
}
现在“在另一门课上”并不能解释太多。但既然你读了一个空值,就意味着你在这里写了一个空值。这意味着在这个“其他类”中,至少在这个方法中,
bandList=null

使用您提供的代码,我不可能深入研究这个问题,但在“另一个类”中,您获得了一个名为bandList的类属性,但没有在其中放入任何内容


或者你把一切都保存好了,但没有打电话

BandList bandList = loadSavedBandList();

以某种形式出现在
if
之前,这也可以很好地解释问题。我是说。。。如果您从未加载带列表,那么它显然将为null…

您从控制台中包括了除NullPointerExcecMetan堆栈之外的所有内容。你能编辑你的帖子并将其包括在内,然后在这里发表评论,这样我就能看到你做了更改了吗?嗨,我添加了异常堆栈。在updateBandContainer()方法中,它通过迭代Band列表来更新BandsContainer,并将每个Band添加为一个按钮。那么代码是什么,具体来说是第95行?在帖子的行中添加了“for”。谢谢你的帮助。你发了几行“for”是什么意思?您不可能引用for循环,因为它引用了上面一行使用的变量。您是否尝试使用调试器运行此命令以检查哪些变量为空?
BandList bandList = loadSavedBandList();