为什么从另一个方法调用 DateTime.withTime() 会导致 exceptionInInitializerError

Why does calling DateTime.withTime() from another method cause an exceptionInInitializerError

这段代码直到几天前才有效。现在它不再适用于 android 6.0 版。它适用于 7.0 及更新版本。

public void setToDate(String quickDate) {
    DateTime toDate = new DateTime();

    if (quickDate.equals(context.getString(R.string.quickDate_today))) {
        fromDate = fromDate.withTimeAtStartOfDay();
        toDate = DateUtils.endOfDay(toDate);
    }
    ....        
}


 /**
 * @return a copy of dateTime with the time set to 11:59:59.999 pm.
 */
public static DateTime endOfDay(DateTime dateTime) {
    return dateTime.withTime(23, 59, 59, 999);
}

奇怪的是,如果我将 withTime() 调用移动到直接调用而不是像这样在实用方法中调用:

public void setToDate(String quickDate) {
    DateTime toDate = new DateTime();

    if (quickDate.equals(context.getString(R.string.quickDate_today))) {
        fromDate = fromDate.withTimeAtStartOfDay();
        toDate = toDate.withTime(23, 59, 59, 999);
    }
    ....        
}

然后代码工作,没有抛出异常。为什么?我怎样才能让它再次在实用方法中工作?

堆栈跟踪:

Process: com.salesrabbit.android.sales.universal, PID: 29358
java.lang.ExceptionInInitializerError
    at com.salesrabbit.android.sales.universal.canvass.filter.filters.Filter.setQuickFromAndToDates(Filter.java:273)
    at com.salesrabbit.android.widget.FilterView.lambda$loadQuickDateMenu$FilterView(FilterView.java:203)
    at com.salesrabbit.android.widget.FilterView$$Lambda.onMenuItemClick(Unknown Source)
    at android.support.v7.widget.PopupMenu.onMenuItemSelected(PopupMenu.java:108)
    at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
    at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)
    at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973)
    at android.support.v7.view.menu.MenuPopup.onItemClick(MenuPopup.java:127)
    at android.widget.AdapterView.performItemClick(AdapterView.java:310)
    at android.widget.AbsListView.performItemClick(AbsListView.java:1145)
    at android.widget.AbsListView$PerformClick.run(AbsListView.java:3066)
    at android.widget.AbsListView.run(AbsListView.java:3903)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5417)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
 Caused by: java.lang.IllegalArgumentException: Unknown pattern character 'X'
    at java.text.SimpleDateFormat.validatePatternCharacter(SimpleDateFormat.java:323)
    at java.text.SimpleDateFormat.validatePattern(SimpleDateFormat.java:312)
    at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:365)
    at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:258)
    at com.salesrabbit.android.util.DateUtils.<clinit>(DateUtils.java:31)

您可能知道 - 当 Java 无法创建 class 的实例时抛出 ExceptionInInitializerError - 它通常表示构造函数中的错误,但也可能来自class.

示例(由于静态块,无法创建此 class,您会看到错误):

class MyClass {

    private static boolean canDivideByZero;
    private Object unassignedValue;

    static {
         //Of course this code is ridiculous, it's just an example
         canDivideByZero = (10/0 == 10);
    }

    public MyClass() {
        //The stupid NPE here would also manifest as an ExceptionInInitializerError 
        if ( unassignedValue.equals("") ) {
            ...
        }
    }

}

虽然您没有包含所需的堆栈跟踪,但您的评论为我们提供了线索

Here is the weird thing, If I move the withTime() ... Then the code works, no exceptions thrown

所以问题可能是您的实用程序 class 不可实例化,或者您正在调用的方法中的某些内容已损坏 - 而您是从构造函数调用它。请记住,实用程序 class 确实应该是最终的,带有不执行任何操作的私有构造函数。


注意:在 OP 的特定示例中,静态变量试图使用来自另一个 SDK 的值是原因。这是我在上面的示例中没有涉及的内容 - 静态块和静态变量都在加载 class 时初始化,并且都可以抛出此异常。