簡體   English   中英

從另一個類訪問的靜態ArrayList始終為空

[英]Static ArrayList accessed from another class is always empty

我有以下課程

import java.util.ArrayList;
import java.util.List;

public class TestStaticArrayList {

    public static List<String> numberList = new ArrayList<String>();

    public static List<String> getArrayValues(){
    return numberList;
    }

    public static void populateArray() {
    numberList.add("1");
    numberList.add("2");
    numberList.add("3");        
    }
}

上一類中的靜態ArrayList是從下一類的調用中動態填充的。

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class TestStaticInvokationClass {

    public static void main(String[] args) throws Exception {

    Class staticKlass = Class
        .forName("com.sathish.test.TestStaticArrayList");
    staticKlass.getMethod("populateArray", null).invoke(null, null);
    }
}

我正在嘗試訪問以下類中的靜態ArrayList,但它始終為空。

public class StaticArrayListAccessTest {

    public static void main(String[] args) throws Exception {   
    System.out.println(TestStaticArrayList.getArrayValues());

    }
}

如果我使用

static {
...
}

填充Arraylist可以正常工作。 我有一個用例,其中ArrayList是動態填充的,這意味着我不能使用靜態{..}塊。在這種情況下,如何訪問靜態ArrayList。

在這方面的任何幫助表示贊賞。

靜態字段保留其整個程序執行價值,但只在一個執行。 靜態字段的目的是使值可用,而不必獲取任何類的實例。 僅一個主方法將被隱式調用,因此將填充並忘記該列表,或者將從另一個入口點讀取空列表。

static { }阻止工作的原因是, 無論入口點是什么,它們都會在檢索列表之前的某個時間運行。

因此,以下內容將起作用:

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class TestStaticInvokationClass {

    public static void main(String[] args) throws Exception {

    Class staticKlass = Class
        .forName("com.sathish.test.TestStaticArrayList");
    staticKlass.getMethod("populateArray", null).invoke(null, null);
    System.out.println(TestStaticArrayList.getArrayValues());
    }
}

它將填充ArrayList,然后嘗試在同一執行中讀取它。

無論如何 ,您無需使用反射,因為在這種情況下反射速度更慢,風險更高且沒有必要。 只需執行以下操作:

TestStaticArrayList.populateArray();

當然,它將是空的。 永遠不會調用方法populateArray() 如果需要查看填充的列表,則需要執行以下操作:

TestStaticArrayList.populateArray();
TestStaticArrayList.getArrayValues();

僅供參考,我強烈建議您更改代碼結構。 靜態動態是兩個截然不同的概念,這是有原因的!

來自評論:“是的,我很好奇為什么它可以使用靜態塊而不是靜態方法”

初始化類時,將自動調用靜態初始化塊。 TestStaticArrayList初始化? 就在這里,當您首次訪問其靜態方法/字段之一時( 這里是有關初始化的更多信息):

System.out.println(TestStaticArrayList.getArrayValues());

當您打印結果時,靜態初始化塊將已經運行。 但是,如果您沒有任何靜態初始化塊,則在代碼中就不會放置ArrayList 這就是為什么在第二個程序中ArrayList為空的原因。 您可以將其填充在自動運行的靜態初始化塊中,或者在打印其值之前顯式調用populateArray()

一個類不只是被“執行”,因為它具有main方法。 這樣的方法是啟動程序的切入點。 如果這不是您的切入點,則必須顯式調用相應的方法。

當您調用TestStaticArrayList.getArrayValues() ,它將不會在其中執行main方法。

如果您執行該程序兩次,它將不會知道上一次列表中的值:每個工作彼此分開。

暫無
暫無

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

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