首页 > 解决方案 > 方法退出时新的 ArrayList 对象消失

问题描述

您好,提前致谢。我在这里相对较新,到目前为止,我已经能够解决我在搜索中遇到的任何问题,但这让我很困惑。

我正在编写一个程序,该程序使用 Rest-Assured 进行 API 调用以获取云服务器中不同对象的配置文件。这些对象是我们可以称之为文件夹的组织文件容器。这些文件夹具有特定的结构,每个文件夹都有特定的元数据配置文件。我的程序所做的是从返回的 JSON 中创建 java 对象,并以允许它们仍然像文件夹结构一样工作的方式存储它们,以便可以操作它们来执行以下操作:打印文件夹结构,获取特定的子文件夹文件夹、查看特定文件夹的名称或 ID、添加或删除文件夹等。

我已经进行了设置,以便每个文件夹都是一个对象,其中包含其子文件夹的 ArrayList 和元数据变量,其中构造函数将根据 JSON 填充所有变量。

在使用我的递归方法调用 API 并将子文件夹添加到它们应该去的位置之后,在类内部的方法中,我可以看到它们已正确添加,一旦方法退出,如果我尝试从 Main 访问列表我得到一个空指针异常。请参阅下面的代码示例。

编辑:我在下面的代码中添加了额外的测试,以检查递归方法中的数组索引是否为空。创建对象时,构造函数使用 . 打印 ArrayList 中的文件夹 ID 和索引indexOf()。当它以相同的递归方法从构造函数返回时,getSingleFolder(index).getSubfolders().get(0).getSubfolders().get(0).toString它仍然为 null,即使这应该返回刚刚从构造函数中创建并添加到父文件夹 ArrayList(并已验证)的相同文件夹。

        public void saveSubfoldersRecursively(Folder folder){
        if (folder.hasSubfolders()){
            getFolderSubfoldersJsonArrayFromRestApi(folder);

            for(int x = 0; x < folder.getFoldersJsonArray().size(); x++) {
                JsonObject currentSubfolderJson = folder.getFoldersJsonArray().get(x).getAsJsonObject();
                JsonObject fullSubfolderProfileObject = getFolderProfileFromRestApi(currentSubfolderJson);
                Folder newSubfolder = folder.addSubfolder(fullSubfolderProfileObject);

                if (newSubfolder.hasSubfolders()) {
                    saveSubfoldersRecursively(newSubfolder);
                }
            }
            if (folder.getId().equals("<folderID>") ) {
                System.out.println("inside saveSubfoldersRecursively");  // this prints fine
// Null Pointer Exception at next line!
                System.out.println("access test 1: " + folder.getId() + " subfolder at index 0: " + folder.getSubFolders().get(0)); 
        }
    }

根据要求,getFolderProfileFromRestApi()andgetFoldersJsonArrayFromRestApi()方法只需使用 Rest-Assured 进行调用并返回一个 GSON JsonObject,其中包含构造函数所需的信息或它们的功能所需的方法,我已经使用了很多并验证了它们是否正常工作如预期。调用folder.addSubfolder()调用文件夹构造函数并返回新文件夹,以便它可以用于获取它自己的文件夹等。我已经非常广泛地使用它并验证它确实返回了正确的信息并调用了构造函数。如果我将 System.out 检查放在实际folder.addSubfolder()方法中,我可以访问数组中的元素,因为它们仍然存在,但当控制返回主时似乎消失了。

Folder 类中的 addSubfolder 方法如下所示。我添加了系统输出来检查并确保一切都在发生,实际上这些都添加到了它们应该添加的位置。这里的输出完全符合预期。

public Folder addSubfolder(JsonObject folderProfile){
    System.out.println("Adding " + folderProfile.get("id") + " to subfolders of " + this.getId());        //this is a check to be sure the folderProfile passed has the right folderID and has been passed ot the right parent folder. this also returns the correct info in all cases
    Folder subfolder = new Folder(folderProfile);
    this.subFolders.add(subfolder);
    System.out.println("subfolder added at index " + this.subFolders.indexOf(subfolder));    //This is just a check to see that the subfolder is now in the array and it does return the correct index. 
    return subfolder;
}

当我返回 Main 时,我编写了一个小的递归方法,以仅使用名称的标准格式打印结构,它似乎可以工作,直到它到达一个有 3 级的地方,然后它抛出一个 null尝试访问该级别的第一个元素时的指针异常。

相反,我使用特定代码为刚刚创建并在 addSubfolder 方法中检查的确切嵌套子文件夹调用 toString,它还返回空指针异常。IE

server.getSinglefolder(1).getSubFolders().get(0).getSubFolders().get(0).toString();

据我所知,这另一个 StackOverflow 帖子

ArrayList 对象消失

有同样的问题,但我似乎无法理解如何根据我的情况转换解决方案,或者它是否不起作用,因为我不应该这样做。谢谢你的帮助!

编辑:我再次查看了该帖子,似乎他的问题是他后来的代码正在更改它,但他没有注意到,因为它是一个参考。我不认为这是这种情况,因为在该方法返回后,该对象不会再次被访问,直到它在 main 中调用并返回为空。我现在整天都在搜索和阅读文章,这一定是我看不到的愚蠢的东西。再次感谢你的帮助。

编辑 2:经过进一步测试,我注意到添加到 ArrayList 的文件夹在构造函数中是可验证的,this用于获取对象并为其 ID 调用 getter。但是,当从调用构造函数的递归方法的末尾访问时,ArrayList 在该索引处为空(添加到代码示例的 System.out 测试)。因此,实际上,只要构造函数返回,arraylist 在控制甚至返回到 main 之前再次为 Null。这可能与我在方法中声明占位符对象(文件夹、子文件夹、newSubfolder)并因此在退出时被清除的事实有关吗?即使是这种情况,即使临时引用消失,对象本身也应该保留更改。

编辑3:根据要求,这里是folder.hasSubFolders()文件夹构造函数的方法。

private boolean hasSubfolders;


    public boolean hasSubfolders() {
    return hasSubfolders;
}

从 addSubfolder 中调用的文件夹构造函数。请注意,整个构造函数大约 150 行,但格式相同,检查 JSON 中的成员,如果存在,将值保存到类变量。如果有人真的认为有必要,我可以发布整个内容。

 //main constructor, parses response string to JSON and pulls all data to fill class variables.
public Folder(JsonObject folderProfile) {

    if (folderProfile.has("database")) {
        this.database = folderProfile.get("database").getAsString();
    }

    if (folderProfile.has("default_security")) {
        this.defaultSecurity = folderProfile.get("default_security").getAsString();
        }
...}

编辑5:程序每个部分的ideone链接。它当然不会在没有访问其余服务器的情况下运行,但不幸的是我无法共享连接信息。我可以向您保证,其余调用正常运行并准确返回其应有的数据,并且所有这些数据都得到了正确处理(以一种可行的方式正确处理,但可能不是最佳实践)-_-

注意:我知道我需要清理抽象类及其实现方式,我还有很多工作要做来清理编码实践,但这还远未完成,只是完成了一半我正在测试的程序。但是,由于我一直在学习,因此我完全愿意接受该领域的任何建议。谢谢

主要 - https://ideone.com/Y2FYrm

IMContainer - https://ideone.com/TFdiqk

文件夹 - https://ideone.com/gX4nda

模板 - https://ideone.com/7VfkPX

服务器 - https://ideone.com/geJazD

标签: javaarraylist

解决方案


我怀疑当您递归地将文件夹添加到文件夹 arrayList 时,您没有将子文件夹添加到添加的子文件夹中。这会创建一个场景,其中第三次递归的子文件夹会引发 NullPointerException。如果这是唯一的问题,搬家

if (newSubfolder.hasSubfolders()) {
    saveSubfoldersRecursively(newSubfolder);
}

到方法的开头可能会有所帮助。

但是,在不知道实现的情况下

getFolderSubfoldersJsonArrayFromRestApi

或者

getFolderProfileFromRestApi

我不能肯定地说。


推荐阅读