2011-01-25 100 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()); 
     } 
    }