是否可以在类中重新初始化静态可变字段?

时间:2017-04-05 15:36:57

标签: java reflection dynamic-class-loaders

我正在尝试自动化用于解决竞争性编程挑战的定制编写程序的测试过程。下面是解决方案的虚拟示例实现:

public class Solution {
    private static String dummyField = "initial";


    public static int initialize(InputStream in) {
        //competitive programmer custom code
        System.out.println(dummyField);
        dummyField = "changed";
        return subCaseCount;
    }

    public void processSingleSubCase(InputStream in) {
        //competitive programmer custom code
    }
}

预先编写的解决方案测试代码,无论其实现如何:

public void testSolution() throws FileNotFoundException {
        for(File testResource : testResources) {
            InputStream in = new FileInputStream(testResource);
            int subCaseCount = Foo.initialize(in);
            for (int subCase = 0; subCase < subCaseCount; subCase++) {
                new Foo().processSingleSubCase(in);
            }

            //magic call to re-init all static fields without knowing their number/names in advance goes here
        }

        //console current output:
        //initial
        //changed
        //changed
        //...

        //desired:
        //initial
        //initial
        //initial
        //....
}

静态字段可以是可变的,因此缓存初始值并使用反射作为第一个设置将它们映射到字段名称,然后在迭代之间重新分配它们不会。

我确实设法提出了一个工作解决方案,基本上在迭代之间使用不同的类加载器重新加载类,它确实有效但速度很慢:只需重新加载类需要 50秒 300次(测试资源是自动生成的,我希望能够灵活地自动生成尽可能多的数据)。

有更快的替代方案吗?

1 个答案:

答案 0 :(得分:1)

我对如何做到这两点的想法是:

  1. 使用实例而不是static,因为每次测试的新实例都是新的。

  2. 如果您需要(或想要)坚持static s:在第一次测试之前,缓存static值,然后在测试之间从缓存重新分配它们。如果static值是引用可变对象的对象引用,则您需要制作深层副本。