【问题标题】:Trouble reading from Storage从存储读取问题
【发布时间】:2016-10-26 19:00:22
【问题描述】:

我现在对存储系统进行了更深入的了解,但我无法让它正常工作。数据好像保存了,保存的数据肯定不是空的,我还是报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 的 Class,Bands 被添加到其中。

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";
    }
}

因此,在用户填写一些 TextField 的其他类中,乐队被添加到 BandList 中,因此我调用 saveListsToStorage();

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

所以现在,启动App时,App在Storage中寻找Data,如果找到,则返回存储的BandList Object,否则返回一个新的BandList Object。

在此之前,我用

注册了课程
    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,正如 Shai 告诉我的那样,我按照指南中的说明实现了 Externalizable Interface。

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

编辑:

这里是例外:

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();
        }

【问题讨论】:

  • 您包含了除控制台中的 NullPointerExcepiton 堆栈之外的所有内容。您能否编辑您的帖子并将其包含在内,然后在此处发表评论,以便我看到您进行了更改?
  • 嗨,我添加了异常堆栈。在 updateBandContainer() 方法中,它通过遍历 Band List 来更新 BandsContainer,并将每个 Band 添加为一个 Button。
  • 那么代码是什么,特别是第 95 行?
  • 在帖子的行中添加了“for”。感谢您的帮助。
  • 您发布了几行“for”是什么意思?您不可能引用 for 循环,因为它引用了上面一行使用的变量。您是否尝试使用调试器运行它来检查您的哪些变量为空?

标签: codenameone


【解决方案1】:

NullPointerExceptions 是非常了不起的东西,因为它们不仅很容易找出,它们甚至可以向您显示它们发生的确切位置。您所要做的就是查看. 剩下的任何内容并检查它是否为空。一找到问题就发现了。

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

这意味着要么bandList 为空,要么bandList.getBandList() 返回空。快速查看getBandList() 表明它不会为空,因为您在 BandList 类的构造函数中初始化列表。只剩下bandList

遗憾的是你没有发布你从哪里得到的,但我会假设你只是做了类似的事情:

BandList bandList = loadSavedBandList();

那么让我们来看看那个方法。 (顺便说一句:如果你在这个答案的末尾没有这样做,我会多说一些关于你必须看的地方)。

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

让我们再进一步,看看你是如何保存东西的。

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

现在“在其他班级”并没有真正解释太多。但既然你读的是一个空值,这意味着你在这里写的是一个空值。这意味着在这个“其他类”中,至少在这个方法中,bandList = null

使用您提供的代码,我无法深入研究此问题,但似乎在“其他类”中,您有一个名为 bandList 的类属性,但未能在其中放入任何内容。


或者也许你保存了一切正确,但没有调用

BandList bandList = loadSavedBandList();

在您的if 之前以某种形式出现,这也几乎可以解释问题。我的意思是......如果你从不加载bandList,它显然会是空的......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    相关资源
    最近更新 更多