通过反射获取静态字段而不触发初始化?

问题描述 投票:0回答:2

我们有一个 WAR 应用程序,它使用第三方库创建一个线程池,其中一个正在运行的线程作为其内部类之一的静态字段。当我们取消部署 WAR 时,该线程继续运行。为了解决这个问题,我想在取消部署期间运行一些代码,它使用反射来访问私有静态字段并关闭线程池。

线程池是在类的静态初始化程序中创建的。当我们的关闭代码运行时,有问题的类可能尚未加载或初始化,并且我不希望关闭代码初始化该类,只是为了再次关闭它(如果我可以避免这种情况)。

我可以使用

Class.forName()
的三参数形式来获取类而无需初始化它。然而,得到我想要的
Field
后,获取字段的值仍然会触发类被初始化。我正在寻找一种方法来避免这种情况。

这是一些示例代码:

package scratch;
public class A {
    private static final String field;
    static {
        System.out.println("A initializing");
        field = "I'm initialized!";
    }
}

package scratch;
public class B {
    public static void main(String[] args) {
        // var a = new A();
        try {
            System.out.println("B starting");
            var clazz = Class.forName("scratch.A", false, B.class.getClassLoader());
            System.out.println("B got class");
            var field = clazz.getDeclaredField("field");
            System.out.println("B got field");
            field.setAccessible(true);
            System.out.println("B set accessible");
            var value = field.get(null);
            System.out.println("B got value '" + value + "'");
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

运行此代码会产生以下输出:

B starting
B got class
B got field
B set accessible
A initializing
B got value 'I'm initialized!'

Field.get()
的调用会触发类的初始化。

我只是想避免在访问该字段的过程中初始化该类(如果尚未初始化)以将其关闭。如果尚未加载类,是否有任何方法可以避免获取该类?或者在获取字段之前测试它是否已初始化?或者在不触发初始化的情况下获取字段的值?

java reflection
2个回答
0
投票

静态块代码在类加载期间仅执行一次。 此时:

    static {
        System.out.println("A initializing");
        field = "I'm initialized!";
    }

类没有初始化,只是加载到JVM中。如果未加载类,则无法通过反射获取类的信息。


0
投票

解决此问题的唯一方法是不要将初始化与类加载联系起来。没关系,因为无论如何这都是个坏主意。所以重写你的类:

public class A {
    private static A LATEST_INSTANCE;
    private String field;
    
    private A() {
        System.out.println("A initializing");
        field = "I'm initialized!";
        LATEST_INSTANCE = this;
    }
}

现在您可以访问

LATEST_INSTANCE
字段并对其状态执行任何您想要的操作。你甚至不需要反思!无论您需要什么,您都可以创建静态方法来访问和访问或初始化实例。

© www.soinside.com 2019 - 2024. All rights reserved.