2012-07-03 38 views
8

Tôi cần phải thay đổi các biến bên trong một lớp bên trong và tôi nhận được sự khét tiếng "Không thể tham chiếu đến biến không phải cuối cùng bên trong một lớp bên trong được định nghĩa trong một phương thức khác".biến không phải lớp cuối cùng bên trong java

void onStart(){ 
    bt.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View v) { 
     int q = i; 
    } 
    }); 
} 

tôi nhanh chóng tạo ra một lớp học mà tổ chức tất cả những điều tôi muốn thay đổi và tạo ra một phiên bản cuối cùng của lớp bên ngoài lớp bên

class temp{ 
    int q; 
} 

void onStart(){ 
    final temp x = new temp(); 
    bt.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View v) { 
     x.q = i; 
    } 
    }); 
} 

này có vẻ là những gì tôi cần và nó làm việc nhưng tôi tự hỏi nếu đây là cách làm việc chính xác xung quanh vấn đề. Ngoài ra, tôi thực sự ghét sử dụng từ temp để đặt tên cho lớp học của tôi. Có một thuật ngữ lập trình thực sự cho những gì tôi đã làm để tôi tạo một tên mô tả hơn cho lớp học của tôi không?

Trả lời

9

Bạn có thể chỉ cần tạo một lớp bên trong thay vì một lớp ẩn danh (như bạn hiện đang làm). Sau đó, bạn có một hàm tạo và bất kỳ phương thức nào khác mà bạn muốn đặt thành viên của mình. Không yêu cầu hackiness (như mảng 1 trường hợp).

Tôi tìm thấy trình dọn dẹp này nếu lớp yêu cầu bất kỳ trao đổi dữ liệu nào với lớp ngoài của nó, nhưng thừa nhận đó là sở thích cá nhân. Mảng thành ngữ 1 cũng sẽ hoạt động tốt và có nhiều chi tiết hơn, nhưng thẳng thắn, nó trông có vẻ kỳ quái. Tôi thường giới hạn các lớp bên trong vô danh cho những người chỉ thực hiện các hành động mà không cố gắng cập nhật dữ liệu trong lớp bên ngoài.

Ví dụ:

private MyListener listener = new MyListener(); 

void onStart(){ 
    bt.setOnClickListener(listener); 
} 

class MyListener implements OnClickListener 
{ 
    String name; 
    int value; 

    void setName(String newName) 
    { 
     name = newName; 
    } 

    void setValue(int newValue) 
    { 
     value = newValue; 
    } 

    public void onClick(View v) 
    { 
     // Use the data for some unknown purpose 
    } 
} 

Nếu có nhiều chủ đề liên quan, sau đó đồng bộ hóa thích hợp sẽ phải được sử dụng như là tốt.

+0

Bravo. Điều tốt đẹp khác là lớp bên trong này có thể mở rộng và tái sử dụng được. IMO, các lớp bên trong vô danh hầu như luôn luôn là một ý tưởng tồi. – user949300

+0

Chúng hoạt động tốt như một lớp kiểu hành động tắt, trình xử lý cho các sự kiện cụ thể trong đó các hành động có thể được thực hiện dựa trên các yếu tố đầu vào. Rất phổ biến trong lập trình GUI, đó là ví dụ của anh ấy. Ngoại trừ trong trường hợp này có sự tương tác giữa các lớp làm phức tạp vấn đề. – Robin

+0

Đây là những gì tôi đang tìm kiếm! Cảm ơn! –

2

Tôi đã đăng câu trả lời tương tự trong số other thread here của mình. Về cơ bản ý tưởng là tạo ra một "wrapper" mà kết thúc tốt đẹp trên khá nhiều bất kỳ loại Object. Kể từ final trong Java là viết tắt của "không phân công lại" và không "liên tục", thủ thuật này khá nhiều công trình ra tốt. Nhưng như đã đề cập trong bài đăng gốc, hãy đảm bảo bạn cẩn thận khi sử dụng nó trong môi trường nhiều luồng.

0

Tôi sẽ giữ tham chiếu đến trình nghe nhấp chuột của bạn ở lớp bên ngoài và tạo biến int thành viên trong trình lắng nghe của bạn. Chỉ lưu trữ biến trong trình lắng nghe khi nhấp, sau đó lấy biến trong lớp bên ngoài khi bạn cần, thay vì đặt biến đó tại thời điểm nhấp chuột.

Để đơn giản, nếu lớp bên trong cần thay đổi nó, hãy biến nó thành một biến trong lớp bên trong.

0

Vì bạn có vẻ đang thiết lập nhiều thứ (từ nhận xét), hãy tạo một phương thức trong lớp chính, button1WasClicked(), (tên tốt hơn có thể là doUpdate, doSave v.v. - một cái gì đó có liên quan đến nút nào), đặt mã thích hợp ở đó và gọi nó từ lớp bên trong/người nghe. (Nếu bạn đang sử dụng Swing, tôi sẽ biến nó thành Hành động, YMMV)

Bằng cách đó nếu sau đó có một menu hoặc mục đích hoặc cử chỉ cần thực hiện cùng một công cụ, cuộc gọi sẽ có.

Các vấn đề liên quan