Java 从内部类访问变量

Java 从内部类访问变量,java,inner-classes,anonymous-inner-class,Java,Inner Classes,Anonymous Inner Class,我有一些为回调处理程序定义匿名内部类的代码。此处理程序需要分配一个局部变量,请参见下文。我需要在回调中分配resp,并在函数末尾引用它。但是,我在Eclipse中遇到了以下错误: 无法指定最终局部变量resp,因为它是在封闭类型中定义的 我怎样才能解决这个问题 DoorResult unlockDoor(final LockableDoor door) { final UnlockDoorResponse resp; final boolean sent = sendReques

我有一些为回调处理程序定义匿名内部类的代码。此处理程序需要分配一个局部变量,请参见下文。我需要在回调中分配
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());
    }
}

您可以通过为响应创建包装器类来解决这个问题

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

假设这是要更改的代码,那么更改
sendRequest
ResponseAction如何。执行
以返回
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());
    }
}

以下是一个适用于您的黑客:

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());
    }
}
但是,如果您想要更干净的解决方案,则必须为处理程序定义一个命名类,将响应存储在其字段中,并使用访问器方法检索它

致以最良好的祝愿,
Stan.

如果要返回结果,请使用命名的内部类,而不是匿名类。所有其他选项都是丑陋的黑客(一个自我承认;-)

(好的,@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());
        }
    }

ResponseWrapper需要初始化;为什么数组有效,而简单变量无效?因为您没有修改resp[]指向的最终引用。