【问题标题】:Java: ExceptionInInitializerError caused by NullPointerException when constructing a Locale objectJava:构造Locale对象时NullPointerException导致的ExceptionInInitializerError
【发布时间】:2012-05-06 17:35:02
【问题描述】:

我正在为我与其他几个人编写的程序进行本地化。大多数字符串现在从 ini 文件以适当的语言加载。我正在尝试对程序中的货币格式做同样的事情。但是,一旦我尝试启动应用程序,就会遇到运行时异常。

我使用 Locale 对象作为几个 NumberFormat.getCurrencyInstance() 的参数,如下所示:

private static final NumberFormat decf;
static 
{
    decf = NumberFormat.getCurrencyInstance(Lang.cLocale);
    decf.setRoundingMode(RoundingMode.HALF_UP);
}

Lang 是包含所有本地化内容的类。 IDE 在尝试运行时抱怨的代码是 public static Locale cLocale = new Locale(GUI.DB_info[19],GUI.DB_info[20]);

GUI 是包含 GUI 的类,我们决定在其中构造 DB_info 数组(它本身只包含从另一个类中的远程数据库加载的信息)。 DB_info[19] 是语言代码(现在),DB_info[20] 是国家代码(美国)。数组元素正在被正确填充——或者,我现在无法深入了解程序;但是填充 DB_info 的代码没有任何改变。

完整的例外如下:

Exception in thread "main" java.lang.ExceptionInInitializerError
at greetingCard.GUI.<clinit>(GUI.java:118)
Caused by: java.lang.NullPointerException
at java.util.Locale.<init>(Unknown Source)
at java.util.Locale.<init>(Unknown Source)
at greetingCard.Lang.<clinit>(Lang.java:13)
... 1 more

GUI中引用的行是:static String welcome = Lang.L_WELCOME + ", " + empName;,而Lang.java基本上是这样的:

// Set locale for currency display
public static Locale cLocale = new Locale(GUI.DB_info[19],GUI.DB_info[20]); // language, country

// Employee specific strings
public static String L_AMT_REMAIN = "";
public static String L_AMT_TEND = "";
public static String L_APPROVED = "";
public static String L_ARE_YOU_SURE = "";
[...]

public static void Main(String emp_lang)
{
    String header = "";

    if (emp_lang.equals("ENG"))
    {
        header = "ENG";
    }
    else if (emp_lang.equals("SPA"))
    {
        header = "SPA";
    }
    else if (emp_lang.equals("FRE"))
    {
        header = "FRE";
    }
    else if (emp_lang.equals("GER"))
    {
        header = "GER";
    }
    else
    {
        header = "ENG";
    }

    try 
    {
        Ini ini = new Ini(new File("C:/lang.ini"));

        L_AMT_REMAIN = ini.get(header, "L_AMT_REMAIN");
        L_AMT_TEND = ini.get(header, "L_AMT_TEND");
        L_APPROVED = ini.get(header, "L_APPROVED");
        L_ARE_YOU_SURE = ini.get(header, "L_ARE_YOU_SURE");
                    [...]
                                L_WELCOME = ini.get(header, "L_WELCOME");
        L_WELCOME2 = ini.get(header, "L_WELCOME2");
        L_XACT_CHNG = ini.get(header, "L_XACT_CHNG");  
        L_YES = ini.get(header, "L_YES");

        System.err.println("Employee Language: " + header);
    } 
    catch (InvalidFileFormatException e) 
    {
        e.printStackTrace();
    } 
    catch (IOException e) 
    {
        e.printStackTrace();
    }
} // end public static void main

这是为了让大多数字符串以不同的语言显示。 Lang 内部还有另一种方法可以加载其他一些字符串,与第一组无关。我不相信它会导致这个问题,但如果需要我可以发布它。

这些类/方法的启动顺序如下: GUI.Main 调用 Login 类,该类调用 CreateLogin 方法。该方法调用 Clients.main,它从 GUI 中获取传递给它的 DB_info 数组。客户端填充 DB_info 数组。然后调用 Lang.other(为登录页面获取特定于语言的字符串),并创建登录按钮和标签。一旦登录成功,员工登录的首选语言(从数据库)被传递给 Lang.main 以加载其他字符串(因此 emp_lang 在上面的代码中被传递)。

在我为 Locale 对象添加代码之前,所有这些都运行良好。现在我得到 ExceptionInInitializerError 异常。有谁知道怎么回事?

顺便说一句,从我使用 ini4j 的 ini 文件加载。我在谷歌搜索时发现的一些论坛帖子表明这是一个问题,但我看不出它与 Locale 对象的问题有何关系。 ini 的东西工作(工作)很好。

【问题讨论】:

    标签: java object nullpointerexception locale static-initializer


    【解决方案1】:

    听起来你的静态初始化器中有一个循环,所以有些东西还没有初始化。

    GUI 在获取Lang.L_WELCOME 之前调用Lang 的静态初始化器。 Lang 在第 2 行调用 GUIs 静态初始化程序。您的异常跟踪使它看起来像 GUI 出于某种原因调用 Langs 静态初始化程序。

    总而言之,这样的循环意味着某人将引用一个静态初始化的对象并得到null,而不是他们期望得到的。在这种情况下,我怀疑 Lang.java 第 2 行将两个 null 指针传递给 Locale 构造函数。

    【讨论】:

    • 你是对的。我们通过重新排列一些初始化程序并在两个方法之间划分本地化代码来修复它,以便在需要时调用所有内容。
    • 只是我们在一个不同但在某种程度上相关的问题上需要的线索。谢了。
    【解决方案2】:

    正如 Keith 所说,您有一个静态初始化循环。为了帮助未来的读者...

    为了最小化这些错误,在(复杂的)变量之前初始化(简单的)常量(没有或最少的构造函数),所以这里StringLocale之前——循环引起问题的空间更小。

    在调试方面,NullPointerException 在静态字段上,2 &lt;clinit&gt; 在堆栈跟踪中,早期的类出现在失败的行中,这些线索表明这是一个未初始化的字段通过静态初始化循环

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多