簡體   English   中英

從內部類訪問變量

[英]Accessing variables from inner class

我有一些代碼為回調處理程序定義了一個匿名內部類。 這個處理程序需要分配一個局部變量,見下文。 我需要在回調中分配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());
    }
}

這是一個適用於您的案例的黑客:

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

但是,如果需要更清晰的解決方案,則必須為處理程序定義命名類,將響應存儲在其字段中,並使用訪問器方法檢索它。

最好的問候,斯坦。

您可以通過為響應創建包裝類來解決此問題。

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

假設這是您要更改的代碼,如何更改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());
    }
}

如果要返回結果,則使用命名的內部類而不是匿名類。 提出的所有其他選項是恕我直言丑陋的黑客(一個自我承認;-)

(好的,@ Joel不是,但假設你可以改變你正在實現的界面)

只需使用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());
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM