[英]How might a local float variable become corrupted in Java (Android 8.0.0)?
[英]Local variable become null (Android)
從我的Android應用程序我得到一個奇怪的錯誤消息:NullPointerException(在最后一行代碼)。
public static Integer getDefaultCalendarId(Context context) {
String calendarInSettings = PrefsHelper.getDefaultCalendar(context);
Calendar calendar = PrefsHelper.getCalendarFromPrefKey(context, calendarInSettings);
if (calendar == null || !calendar.canEventEdit()) {
return calculateDefaultCalendar(context);
}
boolean isChecked = false;
for (Calendar checkedCalendar : PrefsHelper.getCheckedCalendars(context)) {
if (checkedCalendar.getId() == calendar.getId()) {
isChecked = true;
break;
}
}
(1114 line) return isChecked ? calendar.getId() : calculateDefaultCalendar(context); // NullPointerException
}
Samsung GT-N7000發生異常。
怎么會發生這種情況?
更新:
calculateDefaultCalendar可以返回null,但getDefaultCalendarId返回值 - 整數(可為空)!
堆棧跟蹤:
java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx.trial/xxx.view.EventEditActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
at android.app.ActivityThread.access$600(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4511)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:986)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:753)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at xxx.EventHelper.java.lang.Integer getDefaultCalendarId(android.content.Context)(SourceFile:1114)
at xxx.view.EventEditActivity.void onCreate(android.os.Bundle)(SourceFile:306)
at android.app.Activity.performCreate(Activity.java:4470)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
... 11 more
java.lang.NullPointerException
at xxx.EventHelper.java.lang.Integer getDefaultCalendarId(android.content.Context)(SourceFile:1114)
at xxx.view.EventEditActivity.void onCreate(android.os.Bundle)(SourceFile:306)
at android.app.Activity.performCreate(Activity.java:4470)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
at android.app.ActivityThread.access$600(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4511)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:986)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:753)
at dalvik.system.NativeStart.main(Native Method)
更新2
calculateDefaultCalendar:
private static Integer calculateDefaultCalendar(final Context context) {
String account = PrefsHelper.getAccountName(context);
if (account != null) {
for (Calendar calendar : PrefsHelper.getCheckedCalendars(context)) {
if (calendar.getOwnerAccount().equals(account) && calendar.canEventEdit()) {
return calendar.getId();
}
}
}
for (Calendar calendar : PrefsHelper.getCheckedCalendars(context)) {
if (calendar.canEventEdit()) {
return calendar.getId();
}
}
return null;
}
更新3
該錯誤定期重復:
產品/ android版本
LT26i_1257-3921 / 4.0.4
MK16i_1249-8137 / 4.0.4
SCH-I500 / 2.3.5
SCH-I500 / 4.0.4
return isChecked ? calendar.getId() : calculateDefaultCalendar(context);
我懷疑calendar.getId()
返回int
而不是Integer
。 這意味着,返回Integer
calculateDefaultCalendar(context)
首先需要自動取消裝箱到int
,並且生成的int
必須自動裝箱到Integer
。 如果isChecked
為false並且calculateDefaultCalendar(context)
返回null
那么這將導致NPE
。 請參閱以下簡化的等效代碼,例如:
class N2 {
public static void main(String args[])
{
System.out.println(check());
}
static Integer check()
{
return false ? 0 : fNull();
}
static Integer fNull()
{
return null;
}
}
搜索相關術語auto-boxing
, NullPointerException
和ternary
會帶來許多類似的熱門。
如果calender.getId()
返回一個int
,則會遇到自動裝箱問題。 由於最可能的罪魁禍首是calculateDefaultCalendar()
的返回值,因此編譯器很可能嘗試自動取消設置null
返回值。 要解決此問題,您只需使用Integer.valueOf(calendar.getId())
手動設置calender.getId()
的返回值。 這將確保返回的值被裝箱為Integer
,然后calculateDefaultCalendar()
的返回值將不會自動取消裝箱。
陳述顯而易見的,其中一個是null:
(已刪除,以前在代碼中成功調用) calendar
從 (消除,以前在代碼中成功調用) getId()
返回
從calculateDefaultCalendar
返回
(刪除,以前在代碼中成功調用) context
看起來calculateDefaultCalendar
由於某種原因返回null。 在我們可以提供幫助之前,我們需要代碼。
好了,現在我們已經calculateDefaultCalendar
,我們可以繼續消除。 從你的評論看,問題是這兩個條件語句
if (calendar.getOwnerAccount().equals(account) && calendar.canEventEdit()) {
return calendar.getId();
}
和
if (calendar.canEventEdit()) {
return calendar.getId();
}
沒有評估為true
(否則他們會返回一個整數,你說)。 所以,接下來要做的就是確保這一點
account
不為空 canEventEdit()
為true 通常,NPE跟蹤就是這樣,它很容易。 只需在代碼中向后工作,直到某些內容為NULL
,這就是源代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.