簡體   English   中英

方法退出時,新的ArrayList對象消失

[英]New ArrayList Objects Disappear When Method Exits

您好,並提前致謝。 我在這里相對較新,到目前為止,我已經能夠解決我從搜索中遇到的任何問題,但這個問題令我難過。

我正在編寫一個程序,使用Rest-Assured進行API調用以獲取雲服務器中不同對象的配置文件。 這些對象是我們可以調用文件夾的組織文件容器。 文件夾具有特定結構,每個文件夾具有特定的元數據配置文件。 我的程序所做的是從返回的JSON創建java對象,並以允許它們仍然像文件夾結構一樣工作的方式存儲它們,以便可以操作它們來執行以下操作:打印文件夾結構,獲取特定的子文件夾文件夾,視圖名稱或特定文件夾的ID,添加或刪除文件夾等。

我已經設置了這個,所以每個文件夾都是一個對象,它包含子文件夾的ArrayList和元數據的變量,構造函數將根據JSON填充所有變量。

在使用我的遞歸方法調用API並將子文件夾添加到它們應該去的位置之后,在類中的方法中我可以看到它們被正確添加,一旦方法退出,如果我嘗試從Main訪問列表我得到一個空指針異常。 請參閱下面的代碼示例

編輯:我已經在下面的代碼中添加了額外的測試,以檢查遞歸方法中的數組索引是否為空。 創建對象時,構造函數使用indexOf()在ArrayList中打印文件夾ID和索引。 當它從構造函數返回時,在同一個遞歸方法中, 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()getFoldersJsonArrayFromRestApi()方法只是使用Rest-Assured進行調用,並返回一個GSON JsonObject,其中包含其函數所需的構造函數或方法所需的信息,我已經使用了這些,已經證實他們按預期工作。 調用folder.addSubfolder()調用文件夾構造函數並返回新文件夾,以便它可以用來獲取它自己的文件夾等。我已經廣泛使用它並驗證它確實返回了正確的信息和構造函數叫做。 如果我將System.out檢查放在實際的folder.addSubfolder()方法中,我可以訪問數組中的元素,因為它們仍在那里但當控制返回到main時似乎消失了。

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嘗試訪問該級別的第一個元素時的指針異常。

相反,我使用特定代碼只調用toString用於剛剛在addSubfolder方法中創建和檢查的完全嵌套子文件夾,並且它還返回空指針異常。

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

我可以告訴,這個其他StackOverflow帖子

對象消失了ArrayList

有同樣的問題,但我似乎無法理解如何為我的情況轉換解決方案或如果它不工作,因為我不應該這樣做。 謝謝你的幫助!

編輯:我已經再次審閱了該帖子,看來他的問題是一個問題,因為他后來的代碼正在改變它,但他沒有注意到因為它是一個參考。 我不認為這是這種情況,因為在該方法返回之后,直到在main中調用該對象並且返回空時才再次訪問該對象。 我現在一直在尋找和閱讀文章,這一定是我看不到的愚蠢。 再次感謝你的幫助。

編輯2:經過進一步測試后,我注意到添加到ArrayList的文件夾在構造函數中是可驗證的,使用this來獲取對象並為其ID調用getter。 但是,當從調用構造函數的遞歸方法的末尾訪問時,ArrayList在該索引處為null(System.out測試添加到代碼示例中)。 因此,一旦構造函數返回,實際上,在控制甚至返回到main之前,arraylist再次為Null。 這可能與我在方法中聲明我的占位符對象(文件夾,子文件夾,newSubfolder)這一事實有關,因此它們會在退出時被清除嗎? 即使是這種情況,即使臨時引用消失,對象本身仍應保持更改。

編輯3:根據要求,這里是folder.hasSubFolders()和文件夾構造函數的方法。

private boolean hasSubfolders;


    public boolean hasSubfolders() {
    return hasSubfolders;
}

從addSubfolder中調用的Folder Constructor。 請注意整個構造函數大約是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

我懷疑當您以遞歸方式將文件夾添加到文件夾arrayList時,您不會將子文件夾添加到添加的子文件夾中。 這會創建一個場景,其中第三個遞歸的子文件夾拋出NullPointerException。 如果這是唯一的問題,移動

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

到方法的開頭可能有所幫助。

但是,不知道實施

getFolderSubfoldersJsonArrayFromRestApi

要么

getFolderProfileFromRestApi

我不能肯定地說。

我同意Chi-Young Jeffrey Lii的回答,這是對此的進一步闡述。 addSubfolder()基本上做了3件事。

public Folder addSubfolder(JsonObject folderProfile){
     System.out.println("Adding " + folderProfile.get("id") + " to subfolders of " + this.getId());
     // 1.create new subfolder
     Folder subfolder = new Folder(folderProfile);
     // 2.add subfolder to this subFolders arraylist
     this.subFolders.add(subfolder);
     System.out.println("subfolder added at index " + this.subFolders.indexOf(subfolder));    
     // 3.return subfolder
     return subfolder;

}

如下圖所示 在此輸入圖像描述

當語句執行時(與圖表顏色匹配高亮顏色),藍色部分是一個空的ArrayList ,如果你調用.get(0) ,它將返回一個null。 如果在null變量上調用toString() ,它將拋出空指針異常。 在此輸入圖像描述 在此輸入圖像描述

由於我們無法訪問所有代碼,因此這是我們可以猜測根本原因的最佳假設。


編輯1

我認為你很困惑為什么在addSubfolder()獲取索引但是當你在saveSubfoldersRecursively()檢查它時,它會給你錯誤。 這是因為兩個陳述指向不同的參考。

System.out.println("access test 1: " + folder.getId() + " subfolder at index 0: " + folder.getSubFolders().get(0)); 

不等於

System.out.println("subfolder added at index " + this.subFolders.indexOf(subfolder));    

我打賭如果你在addSubfolder()的最后一行寫這個也會給你帶來異常。

System.out.println("subfolder's subfolder null check:" + subfolder.getSubFolders().get(0).toString());

編輯2

給出的源代碼說明。 我發現Folder有自己的子文件夾,模板也有自己的子文件夾。 它們是不同的文件夾列表,如何向Template類添加子文件夾可以從模板中檢索回來?

在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM