赋值语句会导致空指针异常吗?
Can an assignment statement cause a null-pointer exception?
此代码片段使用 ExifInterface 读取相机图片 Exif 元数据:
显然,一张特定的图片没有或无效的日期时间和
.getDateTime() 返回空值。在代码中,我将它分配给一个 long、dt,然后
导致如下所示的异常。当然,如果我取消注释 null-check
就在作业之前,一切都很好。
所以,我有 1 个问题和 1 个教训:
我假设 getDateTime() 确实是罪魁祸首。赋值会导致这样的异常吗?
如您所见,有问题的行在 try/catch 内,但它没有捕捉到它,因为
我只捕捉到 IOException。改成Exception的时候就catch了。
String latlong = "";
long dt = 0;
ExifInterface exifInterface;
try {
exifInterface = new ExifInterface(pf.getAbsolutePath());
if (exifInterface != null)
{
float[] latLng = new float[2];
if (exifInterface.getLatLong(latLng)) { //file has exif latlong info
//etc, latLng[0] is your latitute value and latLng[1] your longitude value
latlong = latLng[0] + "," + latLng[1];
}
//if (exifInterface.getDateTime() != null)
dt = exifInterface.getDateTime();
picInfo.comments = exifInterface.getAttribute(ExifInterface.TAG_USER_COMMENT);
}
else
{
System.out.println(">>>>>>>>>>>>>ERROR: cameraPicTask.doInBackground");
System.out.println(">>>>>>>>>>>>>-----: null exifInterface for: " + pf.getAbsolutePath());
}
} catch (IOException e) {
e.printStackTrace();
}
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: com.example.mypics, PID: 7912
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:415)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:305)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference
at com.example.mypics.PicsActivity$cameraPicTask.doInBackground(PicsActivity.java:211)
at com.example.mypics.PicsActivity$cameraPicTask.doInBackground(PicsActivity.java:185)
at android.os.AsyncTask.call(AsyncTask.java:394)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:305)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
好像exifInterface.getDateTime()
returns一个Long
,在这种情况下,它returnsnull
。您将其分配给涉及 unboxing operation 的 long dt
。编译器发出代码,通过调用 longValue()
将 Long
转换为 long
,这会引发 NPE。您可以在堆栈跟踪中看到它:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference
即使您先将其分配给 Long
:
Long dateTime = exifInterface.getDateTime();
long dt = dateTime;
它仍然需要拆箱,因此,是的,一个作业可以抛出一个 NullPointerException
。
此代码片段使用 ExifInterface 读取相机图片 Exif 元数据: 显然,一张特定的图片没有或无效的日期时间和 .getDateTime() 返回空值。在代码中,我将它分配给一个 long、dt,然后 导致如下所示的异常。当然,如果我取消注释 null-check 就在作业之前,一切都很好。
所以,我有 1 个问题和 1 个教训:
我假设 getDateTime() 确实是罪魁祸首。赋值会导致这样的异常吗?
如您所见,有问题的行在 try/catch 内,但它没有捕捉到它,因为 我只捕捉到 IOException。改成Exception的时候就catch了。
String latlong = ""; long dt = 0; ExifInterface exifInterface; try { exifInterface = new ExifInterface(pf.getAbsolutePath()); if (exifInterface != null) { float[] latLng = new float[2]; if (exifInterface.getLatLong(latLng)) { //file has exif latlong info //etc, latLng[0] is your latitute value and latLng[1] your longitude value latlong = latLng[0] + "," + latLng[1]; } //if (exifInterface.getDateTime() != null) dt = exifInterface.getDateTime(); picInfo.comments = exifInterface.getAttribute(ExifInterface.TAG_USER_COMMENT); } else { System.out.println(">>>>>>>>>>>>>ERROR: cameraPicTask.doInBackground"); System.out.println(">>>>>>>>>>>>>-----: null exifInterface for: " + pf.getAbsolutePath()); } } catch (IOException e) { e.printStackTrace(); }
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: com.example.mypics, PID: 7912
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:415)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:305)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference
at com.example.mypics.PicsActivity$cameraPicTask.doInBackground(PicsActivity.java:211)
at com.example.mypics.PicsActivity$cameraPicTask.doInBackground(PicsActivity.java:185)
at android.os.AsyncTask.call(AsyncTask.java:394)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:305)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
好像exifInterface.getDateTime()
returns一个Long
,在这种情况下,它returnsnull
。您将其分配给涉及 unboxing operation 的 long dt
。编译器发出代码,通过调用 longValue()
将 Long
转换为 long
,这会引发 NPE。您可以在堆栈跟踪中看到它:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'long java.lang.Long.longValue()' on a null object reference
即使您先将其分配给 Long
:
Long dateTime = exifInterface.getDateTime();
long dt = dateTime;
它仍然需要拆箱,因此,是的,一个作业可以抛出一个 NullPointerException
。