2011-01-25 21 views
10

Tôi có một số mã định nghĩa một lớp bên trong vô danh cho trình xử lý gọi lại. Trình xử lý này cần gán một biến cục bộ, xem bên dưới. Tôi cần phải chỉ định resp trong gọi lại và tham chiếu đến phần cuối của hàm. Tôi nhận được lỗi này trong Eclipse tuy nhiên:Truy cập các biến từ lớp bên trong

Các thức địa phương biến resp không thể được chỉ định, vì nó được định nghĩa trong một loại kèm theo

Làm thế nào tôi có thể sửa lỗi này?

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

Trả lời

3

Bạn có thể giải quyết vấn đề này bằng cách tạo lớp trình bao bọc cho phản hồi.

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

Sau đó, mã của bạn sẽ trông như thế:

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 cần được khởi chạy. – Joel

+0

@ Joel, cảm ơn vì đã chỉ ra điều đó. Đã sửa. – jjnguy

+0

@Erick, tại sao điều này không hoạt động? – jjnguy

1

Giả sử đây là mã của bạn để thay đổi, làm thế nào về việc thay đổi sendRequestResponseAction.execute trở về một thể hiện của 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

đây là một hack sẽ hoạt động trong trường hợp của bạn:

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

Nếu bạn muốn có giải pháp sạch hơn, bạn phải xác định một lớp được đặt tên cho trình xử lý của bạn, lưu trữ phản hồi trong trường của nó và truy xuất phản hồi bằng phương thức truy cập.

Trân trọng, Stan.

+3

Hack thú vị; tại sao mảng làm việc nhưng biến đơn giản thì không? –

+3

vì bạn không sửa đổi tham chiếu cuối cùng cho các điểm resp []. – Joel

0

Nếu bạn định trả lại kết quả, hãy sử dụng lớp bên trong có tên thay vì một lớp ẩn danh. Tất cả các tùy chọn khác được trình bày là hacks IMHO xấu xí (một tự thừa nhận ;-)

(OK, @ Joel không phải là nhưng giả sử bạn có thể thay đổi giao diện bạn đang thực hiện)

Chỉ cần tạo một thể hiện của lớp với một getter cho kết quả, nó được sạch sẽ và chỉ yêu cầu bạn phải thực hiện các lớp đơn.

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

Bạn quá tốt bụng! – Joel