Java:如何“重新启动”静态类?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4631565/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 07:17:53  来源:igfitidea点击:

Java: how to "restart" a static class?

staticjunitjava

提问by Topera

I have a static class (Foo) and a main class (Main)

我有一个静态类 (Foo) 和一个主类 (Main)

See Main.java:

参见 Main.java:

public class Main {

    public static void main(String[] args) {
        System.out.println(Foo.i); // 0
        Foo.i++;
        System.out.println(Foo.i); // 1
        // restart Foo here 
        System.out.println(Foo.i); // 1 again...I need 0
    }

}

See Foo.java:

参见 Foo.java:

public class Foo {

    public static int i = 0;

}

Is there any way to restart or reset a static class?

有没有办法重新启动或重置静态类?

Note: I need this because I'm testing a static class with jUnit and I need to clean parameters before second test.

注意:我需要这个,因为我正在用 jUnit 测试一个静态类,我需要在第二次测试之前清理参数。



EDIT

编辑

ALMOST SOLUTION:

几乎解决方案:

Using StanMax answer, I can to this:

使用 StanMax 答案,我可以这样做:

Main.java

主程序

public class Main {

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

    public static void test() throws Exception {

        System.out.println("\ntest()");

        MyClassLoader myClassLoader = new MyClassLoader();
        Class<?> fooClass = myClassLoader.loadClass(Foo.class.getCanonicalName());

        Object foo = fooClass.newInstance();
        System.out.println("Checking classloader: " + foo.getClass().getClassLoader());

        System.out.println("GC called!");
        System.gc();
    }

}

MyClassLoader.java

MyClassLoader.java

public class MyClassLoader {

    private URLClassLoader urlClassLoader;

    public MyClassLoader() {
        try {
            URL url = new File(System.getProperty("user.dir") + "/bin/").toURL();
            URL[] urlArray = {url};  
            urlClassLoader = new URLClassLoader(urlArray, null);  
        } catch (Exception e) {
        }
    }

    public Class<?> loadClass(String name) {
          try {
            return (Class<?>) urlClassLoader.loadClass(name);
        } catch (Exception e) {
        }
        return null;
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("MyClassLoader - End.");     
    }


}

Foo.java

文件

public class Foo {

    public static int i = 0;

    static {
        System.out.println("Foo - BEGIN ---------------------------------");
    }

    public void finalize() throws Throwable {
        System.out.println("Foo - End.");
    }


}

OUTPUT

输出

test()
Foo - BEGIN ---------------------------------
Checking classloader: java.net.URLClassLoader@ec160c9
GC called!
MyClassLoader - End.
Foo - End.

test()
Foo - BEGIN ---------------------------------
Checking classloader: java.net.URLClassLoader@ec3fb9b
GC called!
MyClassLoader - End.
Foo - End.

PROBLEM:if I do the cast bellow:

问题:如果我做下面的演员表:

Foo foo = (Foo) fooClass.newInstance();

I get error:

我得到错误:

java.lang.ClassCastException

采纳答案by StaxMan

Only if you can unload class, get it re-loaded, as class static code gets executed when class is loaded.

只有当您可以卸载类时,才能重新加载它,因为类加载时会执行类静态代码。

But you can just directly modify the value:

但是你可以直接修改值:

Foo.i = 0;

(or create equivalent method for doing it, esp. if static member is not public)

(或创建等效的方法来执行此操作,尤其是如果静态成员不是公共的)

回答by martin clayton

Create a static method that sets the class variables to their initial values, then call it when you need it.

创建一个静态方法,将类变量设置为其初始值,然后在需要时调用它。

回答by akuhn

Avoid static.

避免静电。

It is well known that static is not testable and should thus be avoided. For example, avoiding static is one of the key motivations behind dependency injection. If you need one instance only at runtime, use the singleton pattern instead. And create a new instance for each test run.

众所周知,静态是不可测试的,因此应该避免。例如,避免静态是依赖注入背后的主要动机之一。如果您只在运行时需要一个实例,请改用单例模式。并为每次测试运行创建一个新实例。

回答by Lee

You can try this.

你可以试试这个。

Main MainObject = new Main;

MainObject.main(args);

It will restart the class again and again until you stop the class.

它会一次又一次地重新开始上课,直到您停止上课为止。