赋值语句会导致空指针异常吗?

Can an assignment statement cause a null-pointer exception?

此代码片段使用 ExifInterface 读取相机图片 Exif 元数据: 显然,一张特定的图片没有或无效的日期时间和 .getDateTime() 返回空值。在代码中,我将它分配给一个 long、dt,然后 导致如下所示的异常。当然,如果我取消注释 null-check 就在作业之前,一切都很好。

所以,我有 1 个问题和 1 个教训:

  1. 我假设 getDateTime() 确实是罪魁祸首。赋值会导致这样的异常吗?

  2. 如您所见,有问题的行在 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 operationlong 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