有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java从内部类访问变量

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

共 (4) 个答案

  1. # 1 楼答案

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

    (好的,@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());
            }
        }
    
  2. # 2 楼答案

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

    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());
    }
    
  3. # 3 楼答案

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

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

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

    致以最良好的祝愿, 斯坦

  4. # 4 楼答案

    假设这是要更改的代码,那么更改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());
        }
    }