java:有什么办法可以避免编写命名类吗? (变量尚未初始化)

时间:2016-08-03 15:38:37

标签: java

在一个地方(并且只有一个)我需要一个围绕传递给该方法的接口的包装器。如果可能的话,我希望通过为此目的编写单独的类来避免使代码复杂化,所以我想采用闭包方法,但后来我遇到了#34;变量可能没有被初始化"错误。

我发现了类似的问题(Final Local Variable may not have been initialized in anonymous inner class),但如果可能的话,我想找到解决问题的方法,而不必为包装器编写单独的类。

代码:

    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);
}

其他详情:

  • 作为参数传递的侦听器可能无法访问google api客户端(我使用几种不同的方式来提供所需的位置',并在其他实现中重新使用LocationListener接口),所以我无法从位置更新中删除它的onLocationChanged方法
  • 可能有多个监听器,所以我不能将它保存在类级变量中(我必须使用一些集合和逻辑来通知哪一个请求了什么以及什么时候)
  • 此代码中位置请求的通常用例是根据用户的操作获取单个位置更新(例如打开地图,或点击"刷新"按钮) - &#39 ;为什么我想立即删除听众。

2 个答案:

答案 0 :(得分:2)

与Java中一样,当你有一个初始化程序(或任何赋值语句)时,首先要计算要分配的表达式,然后才将它赋值给变量。

对于本地变量l也是如此 - 在您创建匿名类时,l还没有值 - 它只会在匿名类的实例之后有一个已经建成并分配给它。

当然,你不能从封闭中引用一个未初始化的变量,而这就是你遇到问题的原因。

解决方案是使用this从其中引用该实例,而不是使用l。您可以在匿名类中使用this,而不是lambda表达式,其中this指的是封闭类。

答案 1 :(得分:1)

不是试图将局部变量l传递给removeLocationUpdates(),而是触发错误,只需传递this作为参数。这是有效的,因为在该匿名类的上下文中,this引用了匿名类实例(LocationListener

LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);