我无法在我的身边产生空指针异常。但是,我确实从用户那里收到了很多空指针异常崩溃报告。

public static Currency getStockCurrency(PortfolioRealTimeInfo portfolioRealTimeInfo, Code code) {
    //////////////////////////////////////////
    // Get traded currency in this stock code.
    //////////////////////////////////////////
    final Currency stockCurrency;
    org.yccheok.jstock.engine.currency.Currency c = portfolioRealTimeInfo.currencies.get(code);
    if (c == null) {
        Country stockCountry = org.yccheok.jstock.engine.Utils.toCountry(code);
        stockCurrency = stockCountry.stockCurrency;
    } else {
        stockCurrency = c;
    }
    return stockCurrency;
}

public static double getExchangeRate(PortfolioRealTimeInfo portfolioRealTimeInfo, Currency localCurrency, Code code) {
    final Currency stockCurrency = getStockCurrency(portfolioRealTimeInfo, code);

    return getExchangeRate(portfolioRealTimeInfo, localCurrency, stockCurrency);
}

public static double getExchangeRate(PortfolioRealTimeInfo portfolioRealTimeInfo, Currency localCurrency, Currency stockCurrency) {
    // Possible null.
    if (localCurrency == null) {
        if (stockCurrency.toString().equals("GBX")) {


NPE在线发生

if (stockCurrency.toString().equals("GBX")) {


但是我不明白


stockCurrency永远不能为null,因为
getStockCurrency永远不会返回null,因为
stockCurrency = stockCountry.stockCurrency;stockCountry不为null,因为此时不会发生崩溃。 stockCountry的成员不能为null,因为
stockCountry是一个枚举。我看不到stockCurrency可以为null的任何原因:https://github.com/yccheok/jstock/blob/master/src/org/yccheok/jstock/engine/Country.java#L29
Currency.valueOf永远不能返回null。它可能会抛出异常。但是,我从未收到这样的异常:https://github.com/yccheok/jstock/blob/master/src/org/yccheok/jstock/engine/currency/Currency.java#L52


知道为什么NPE发生在生产线上

if (stockCurrency.toString().equals("GBX")) {


更新资料

某些装有Android 5.0的设备可提供更好的异常信息

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at org.yccheok.jstock.portfolio.m.a(SourceFile:244)
at org.yccheok.jstock.portfolio.m.a(SourceFile:272)
at org.yccheok.jstock.gui.portfolio.BuyPortfolioFragment.b(SourceFile:206)
at org.yccheok.jstock.gui.portfolio.BuyPortfolioFragment.b(SourceFile:314)
at org.yccheok.jstock.gui.portfolio.BuyPortfolioFragment.h(SourceFile:841)
at org.yccheok.jstock.gui.portfolio.BuyPortfolioFragment.a(SourceFile:793)
at org.yccheok.jstock.gui.portfolio.fd.a(SourceFile:521)
at org.yccheok.jstock.gui.portfolio.fd.onLoadFinished(SourceFile:488)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(SourceFile:427)
at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(SourceFile:395)
at android.support.v4.a.o.b(SourceFile:104)
at android.support.v4.a.a.b(SourceFile:223)
at android.support.v4.a.b.a(SourceFile:61)
at android.support.v4.a.q.e(SourceFile:461)
at android.support.v4.a.q.c(SourceFile:47)
at android.support.v4.a.w.handleMessage(SourceFile:474)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5944)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)


看来stockCurrency.toString()已成功执行,但它返回null。但是,我仍然觉得很奇怪,因为stockCurrency.toString()不应该假定返回null。 (这是因为CurrencyvalueOf工厂方法不接受空值)

p / s我正在使用ProGuard。但是,我无法想象它如何导致这种神秘的崩溃。

p / s / s应用程序可能会将我定制的Currency与标准java.util.Currency混淆吗?

最佳答案

出现此问题的原因是,Currency对象的创建不是通过常规构造函数或工厂方法完成的。

这是通过Gson序列化完成的。

这是造成这种怪异行为的因素


旧版json字符串是从模糊的Currency类生成的。
在新版本中,我们决定不混淆Currency类。


因此,如果我们通过以下字符串对PortfolioRealTimeInfo进行反序列化

String data = "{\"currencies\":[[{\"code\":\"4677.KL\"},{\"a\":\"MYR\"}],[{\"code\":\"5247.KL\"},{\"a\":\"MYR\"}],[{\"code\":\"5183.KL\"},{\"a\":\"MYR\"}],[{\"code\":\"6947.KL\"},{\"a\":\"MYR\"}],[{\"code\":\"6742.KL\"},{\"a\":\"MYR\"}]],\"stockPrices\":[[{\"code\":\"4677.KL\"},1.67],[{\"code\":\"5247.KL\"},3.18],[{\"code\":\"6947.KL\"},6.04]],\"exchangeRates\":{},\"exchangeRatesTimestamp\":0,\"stockPricesTimestamp\":1430906678615}";


我们会失败的。

请注意,对于{\"a\":\"MYR\"}a是对Currencycurrency成员进行混淆的结果。

当我们决定不混淆Currency时,Gson将“帮助”我们创建一个非空的Currency对象,其成员变量currency为null。

关于java - 为什么enum元素的成员在某些设备中可以为null,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30067809/

10-15 00:50