我无法在我的身边产生空指针异常。但是,我确实从用户那里收到了很多空指针异常崩溃报告。
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#L29Currency.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。 (这是因为Currency
的valueOf
工厂方法不接受空值)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
是对Currency
的currency
成员进行混淆的结果。当我们决定不混淆
Currency
时,Gson将“帮助”我们创建一个非空的Currency
对象,其成员变量currency
为null。关于java - 为什么enum元素的成员在某些设备中可以为null,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30067809/