2011-01-25 97 views
10

我有一些代码为回调处理程序定义了一个匿名内部类。这个处理程序需要分配一个局部变量,见下文。我需要在回调中分配resp,并在函数结束时将其引用。我在Eclipse中收到此错误但是:从内部类访问变量

最后的局部变量resp无法分配,因为它是在一个封闭的类型

我怎样才能解决这个定义?

DoorResult unlockDoor(final LockableDoor door) { 
    final UnlockDoorResponse resp; 
    final boolean sent = sendRequest(new UnlockDoorRequest(door), 
     new ResponseAction() { 
     public void execute(Session session) 
       throws TimedOutException, RetryException, RecoverException { 
      session.watch(UNLOCK_DOOR); 
      resp = (UnlockDoorResponse)session.watch(UNLOCK_DOOR); 
     } 
    }); 
    DoorResult result; 
    if (!sent) { 
     return DoorResult.COMMS_ERROR; 
    } 
    else { 
     return DoorResult.valueOf(resp.getResponseCode()); 
    } 
} 

回答

3

你可以通过创建响应的包装类来解决这个问题。

class ResponseWrapper { 
    UnlockDoorResponse resp; 
    void setResponse(UnlockDoorResponse resp) { 
     this.resp = resp; 
    } 
    UnlockDoorResponse getResponse() { 
     return resp; 
    } 
} 

然后,你的代码看起来像:

final ResponseWrapper respWrap = new ResponseWrapper(); 
final boolean sent = sendRequest(new UnlockDoorRequest(door), new ResponseAction() { 
    public void execute(Session session) throws TimedOutException, RetryException, RecoverException { 
     session.watch(UNLOCK_DOOR); 
     respWrap.setResponse((UnlockDoorResponse)session.watch(UNLOCK_DOOR)); 
    } 
}); 
DoorResult result; 
if (!sent) { 
    return DoorResult.COMMS_ERROR; 
} 
else { 
    return DoorResult.valueOf(respWrap.getResponse().getResponseCode()); 
} 
+0

ResponseWrapper需要初始化。 – Joel 2011-01-25 20:16:08

+0

@Joel,谢谢你的指出。固定。 – jjnguy 2011-01-25 20:17:18

+0

@Erick,为什么这不工作? – jjnguy 2011-01-25 20:18:33

1

假设这是你的代码改变,如何改变sendRequestResponseAction.execute返回的UnlockDoorResponse

DoorResult unlockDoor(final LockableDoor door) { 
    final UnlockDoorResponse resp = sendRequest(new UnlockDoorRequest(door), new ResponseAction() { 
     public UnlockDoorResponse execute(Session session) throws TimedOutException, RetryException, RecoverException { 
      session.watch(UNLOCK_DOOR); 
      return (UnlockDoorResponse)session.watch(UNLOCK_DOOR); 
     } 
    }); 
    if (resp == null) { 
     return DoorResult.COMMS_ERROR; 
    } 
    else { 
     return DoorResult.valueOf(resp.getResponseCode()); 
    } 
} 
5

实例这里是一种黑客,它可以在你的情况下工作:

DoorResult unlockDoor(final LockableDoor door) { 
    final UnlockDoorResponse resp[] = { null }; 
    final boolean sent = sendRequest(new UnlockDoorRequest(door), new ResponseAction() { 
     public void execute(Session session) throws TimedOutException, RetryException, RecoverException { 
      session.watch(UNLOCK_DOOR); 
      resp[0] = (UnlockDoorResponse)session.watch(UNLOCK_DOOR); 
     } 
    }); 
    DoorResult result; 
    if (!sent) { 
     return DoorResult.COMMS_ERROR; 
    } 
    else { 
     return null == resp[0] ? null : DoorResult.valueOf(resp[0].getResponseCode()); 
    } 
} 

但是,如果您想要一个更清晰的解决方案,则必须为您的处理程序定义一个命名类,将响应存储在其字段中,并使用访问器方法检索它。

此致敬礼, 斯坦。

0

如果您要返回结果,请使用命名的内部类而不是匿名类。所有提出的其他选项恕我直言难看黑客(一个自我承认;-)

(OK,@乔尔的不是,但假设你可以改变你实现接口)

只需创建该类的一个背景一个结果的getter,它是干净的,只需要你实现单个类。

class MyReponseAction implements ResponseAction { 
     private UnlockDoorResponse response; 

     public void execute(Session session) throws TimedOutException, RetryException, RecoverException { 
      session.watch(UNLOCK_DOOR); 
      response = (UnlockDoorResponse)session.watch(UNLOCK_DOOR); 
     } 

     UnlockDoorResponse getResponse() { 
      return response; 
     } 
    } 

    DoorResult unlockDoor(final LockableDoor door) { 
     ResponseAction action = new MyResponseAction(); 
     final boolean sent = sendRequest(new UnlockDoorRequest(door), action); 

     DoorResult result; 
     if (!sent) { 
      return DoorResult.COMMS_ERROR; 
     } 
     else { 
      return DoorResult.valueOf(action.getResponse().getResponseCode()); 
     } 
    }