2016-08-03 28 views
2

在一個地方(並且只有一個)我需要一個傳遞給方法的接口的包裝器。如果可能的話,我想避免爲此目的編寫單獨的類而使代碼複雜化,所以我想採用一種閉包方法,但是後來我遇到了「變量可能未被初始化」的錯誤。java:有什麼辦法避免寫命名類? (變量尚未初始化)

我發現了類似的問題(Final Local Variable may not have been initialized in anonymous inner class),但如果可能的話,我想找一種方法來解決這個問題,而不用爲wrapper編寫單獨的類。

的代碼:

protected void startListening(LocationRequest request,@Nullable final LocationListener listener) { 
    ... 
    final LocationListener l = new LocationListener() { 
     @Override 
     public void onLocationChanged(Location location) { 
      if(listener != null) { 
       listener.onLocationChanged(location); 
      } 
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, l); 
     } 
    }; 
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, request, l); 
} 

的附加細節:

  • 聽者作爲參數傳遞可能不能訪問到谷歌API客戶端(I使用幾種不同的方法提供「期望位置」,並且只是在其他實現中重新使用LocationListener接口),所以我無法從位置更新中將其從onLocationChanged方法中移除
  • 可能有多個偵聽器,所以我無法將它保留在class-le (我將不得不使用一些集合和邏輯來通知哪一個請求什麼以及何時請求)
  • 此代碼中位置請求的常見用例是根據用戶的操作獲取單個位置更新(例如,打開地圖,或點擊「刷新」按鈕) - 這就是爲什麼我想立即刪除監聽器。
+2

你有沒有嘗試在'removeLocationUpdates()'的調用中傳遞'LocationListener.this'而不是'l'? –

+0

我得到「com.google.android.gms.location.LocationListener不是封閉類」 - 不知道我可以在內部類中使用'this',它會引用哪個類? 如果'this'引用內部類,那麼我可以用'this'來代替'l'。 – 260

+0

是的,當然可以。實際上'LocationListener.this'是錯誤的語法。 – RealSkeptic

回答

1

,而不是試圖局部變量l傳遞給removeLocationUpdates(),這是什麼觸發了錯誤,只是通過this作爲參數。這工作,因爲在該匿名類的情況下,this指匿名類實例(LocationListener

LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
2

類似於Java往常一樣,當你有一個初始化(或任何賦值語句),首先表達分配計算出來,然後才分配給變量。

這也適用於您的本地變量l - 當您創建匿名類時,l尚未具有值 - 只有在匿名類的實例已構建並分配給它之後纔會有一個值。

所以當然,你不能從閉包中引用一個未初始化的變量,這就是你遇到的問題的原因。

解決方法是使用this從它內部引用該實例,而不是使用l。您可以在匿名類中使用this,與lambda表達式相反,其中this引用封閉類。

+0

(轉換爲OP中的意見回答) – RealSkeptic