【问题标题】:Do I have to make sure classes are loaded manually in Java before I use data they affect?在使用它们影响的数据之前,我是否必须确保在 Java 中手动加载类?
【发布时间】:2021-10-17 20:41:16
【问题描述】:

有点好奇的问题,当我用 java 编写一个看起来有点像这样的程序时:

public class Basic {

    public static HashMap<String,Integer> my_map = new HashMap<>();

    public static void main(String[] a) {
        mymap.forEach( (str,i) -> System.out.println(str+": "+i) );
    }

}

本质上是一个保存和处理一些静态/全局数据的结构,然后说例如(为了代码清洁)我在不同文件中的不同类中的值,它将在初始化时将所有值加载到该主类中像这样:

public class Foo {
    static final String a = def("APPLE");
    static final String b = def("BUMBLEBEE");
    static final String c = def("CARTOGRAPHER");

    static String def (String s) {
        Basic.my_map.put(s, new Random().nextInt(256));
        return s;
    }
}

现在为了让这段代码正常运行(即在程序启动时,Foo 中定义的所有值都被打印出来)我的直觉是在 Foo 中定义一个空函数并在 main 开始时调用它,

我基本上想知道这是否真的有必要。在程序启动之前或至少在使用它们影响的任何代码之前,是否会初始化所有静态变量。或者,在与可能与之交互的数据进行交互之前,最好手动确保已加载一个类。

【问题讨论】:

  • 您刚刚演示了静态成为问题的主要原因之一。但是请注意,由于您从不致电 def,因此没关系。
  • 是的,应谨慎处理静态。我使用该 Java“功能”来进行延迟初始化。仅在访问时加载繁重的资源类。更进一步,当仍然想访问该类中的静态常量但不加载重资源的一部分时,我将重资源访问放置在静态内部类中。
  • 对不起,我错过了这段代码的一个非常重要的方面,def 应该被调用
  • Basic 中没有任何内容引用Foo,因此它永远不会被此代码加载或执行。
  • 啊,是的,不过我的问题是,如果 Foo 中有什么东西是指基本的,编译器是否可以解决这个问题

标签: java class static


【解决方案1】:

一个类在访问时被加载,即使只读取它的一个静态字段,然后它的所有静态字段都将被初始化(如果未分配则为 null),然后任何静态块都会运行。

因此,当您的“填充”类访问需要“填充”类的名称时,它会导致加载。

在您的示例中,没有任何内容调用/引用“Foo”。假设你只是运行 Basic 的 main 方法,那么它应该是空的。

【讨论】:

  • 对不起我写的代码有错误,应该调用def
猜你喜欢
  • 1970-01-01
  • 2010-11-14
  • 1970-01-01
  • 2019-03-04
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多