从另一个类访问的静态ArrayList始终为空

时间:2013-12-09 22:55:43

标签: java arraylist static static-methods static-members

我有以下课程

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

我正在尝试访问下面class中的Static ArrayList。但它总是为空。

public class StaticArrayListAccessTest {

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

    }
}

如果我使用

static {
...
}

填充Arraylist它工作正常。我有一个用例,其中ArrayList是动态填充的,这意味着我不能使用静态{..}块。如何在这种情况下访问静态ArrayList。

对此有任何帮助表示赞赏。

4 个答案:

答案 0 :(得分:5)

静态字段在程序执行期间保留其值,但仅在一次执行中。静态字段的目的是使值可用而无需获取任何类的实例。只会隐式调用一个main方法,因此列表将被填充和遗忘,或者空列表将从另一个入口点读取。

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

答案 1 :(得分:1)

当然,它会是空的。永远不会调用方法populateArray()。如果您需要查看填充的列表,则需要执行以下操作:

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

仅供参考,我强烈建议您更改代码结构。 static dynamic 是两个非常不同的概念!

答案 2 :(得分:1)

来自评论:“是的,我很好奇为什么它适用于静态块而不是静态方法”

初始化类时,静态初始化块自动调用TestStaticArrayList何时初始化?就在这里,当您第一次访问其中一个静态方法/字段时(here更多关于初始化):

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

打印结果时,静态初始化块已经运行。但是,如果您没有任何静态初始化块,则代码中没有填充ArrayList的位置。这就是为什么在你的第二个程序中ArrayList是空的。您可以在静态初始化块中填充它,该块会自动运行,或者在打印其值之前显式调用populateArray()

答案 3 :(得分:0)

一个类不仅仅是“已执行”,因为它具有main方法。这种方法是启动程序的入口点。如果那不是你的入口点,你将必须明确地调用相应的方法。

当您致电TestStaticArrayList.getArrayValues()时,它不会执行main方法。

如果你执行两次程序,它将不会知道最后一次列表中的值:每个工作彼此分开。