2012-03-19 13 views
6

Tôi có một lớp mở rộng JPanel. Trong constructor của nó, tôi đang đi qua this đến các phương thức khác, chủ yếu để thêm đối tượng jpanel như một trình lắng nghe vào các thùng chứa/các điều khiển bên trong jpanel (nhưng các đối tượng khác). Kể từ khi Netbeans cho thấy một cảnh báo leaking this in constructor cho những cuộc gọi tôi đã đặt chúng trong một phương pháp khác được gọi là từ các nhà xây dựng.Rò rỉ điều này trong hàm tạo - nơi thêm đúng người nghe và các phương thức khác yêu cầu "này"

trước:

class Foo ... { 
    public Foo() { 
     initComponents(); 
     tabX.addChangeListener(this); // <- netbeans complains here 
    } 

sau:

class Foo ... { 
    public Foo() { 
     initComponents(); 
     initListeners(); 
    } 

    protected void initListeners() { 
     tabX.addChangeListener(this); 
    } 

Đó được thoát khỏi những triệu chứng. Nhưng tôi nghi ngờ nó sửa chữa lý do tại sao netbeans cho thấy cảnh báo.
Đâu là nơi thích hợp để thực hiện loại khởi tạo này trong lớp học có nguồn gốc từ JPanel?

+0

không chắc chắn tôi theo dõi, bạn có thể đăng chữ ký phương thức và "sửa" – Woot4Moo

+0

điều này có thể giúp bạn http://stackoverflow.com/questions/3921616/java-leaking-this-in-constructor – Chikei

+0

[Java - Rò rỉ điều này trong constructor] (http://stackoverflow.com/q/3921616/1048330) – tenorsax

Trả lời

0

Tôi cho rằng bạn có thể đang thêm phần mở rộng JPanel vào một số thành phần khác (ví dụ: JFrame, JApplet, một số khác JPanel, v.v.). Bạn đã đề cập rằng bạn đã có một chút pha trộn giữa việc cần thêm bảng điều khiển vào các thành phần phụ trong bảng điều khiển đó và "các đối tượng khác" mà bảng điều khiển cần nghe. Có lẽ sẽ tốt hơn nếu thêm bảng điều khiển vào "các đối tượng khác" gần nơi bạn thêm phần mở rộng JPanel của mình vào thành phần đính kèm JFrame hoặc thành phần cha khác, ngoài định nghĩa lớp của tiện ích mở rộng của bạn.

Tuy nhiên, đối với các thành phần phụ trong bảng điều khiển của bạn phải nghe, tôi cho rằng những gì bạn đang làm là tốt, miễn là các thành phần phụ không hiển thị với các đối tượng bên ngoài định nghĩa lớp mở rộng JPanel của bạn. Cảnh báo chỉ đơn giản là để chỉ ra rằng những gì bạn đang làm có thể không an toàn, nhưng cuối cùng, khi bảng điều khiển của bạn bị thu thập rác, tất cả các thành phần phụ mà nó sở hữu, bao gồm mọi danh sách người nghe họ duy trì điểm đó trở lại tiện ích mở rộng JPanel của bạn. Vì thực tế này, tôi nghĩ rằng việc thực hiện cuộc gọi add*Listener(this) bằng một phương thức riêng được đặt tên khéo léo của tiện ích mở rộng JPanel và gọi nó từ nhà xây dựng của bạn là tốt.

Tùy chọn khác sẽ là sử dụng Eclipse để bạn không nhận được những cảnh báo đó nữa ... (nói đùa hoàn toàn;).

0

Lý do cảnh báo này là bạn đang truyền điều này trong khi hàm tạo không được hoàn thành và do đó đối tượng không được khởi tạo đầy đủ. Thậm chí bạn sử dụng nó ở cuối constructor của bạn, rất có thể là lớp của bạn đã được mở rộng và có một hàm tạo của lớp con sẽ được thực thi. Trong trường hợp của bạn (đăng ký đối tượng như một người nghe) điều này là an toàn, như Swing là đơn luồng và các sự kiện sẽ được truyền cho người nghe chỉ sau khi đối tượng của bạn được khởi tạo.

+1

Đó là lập trình xấu, ngay cả khi trong một môi trường đơn luồng. –

2

Tôi tự hỏi liệu có vấn đề lớn hơn khi chơi ở đây hay không - yêu cầu lớp học của bạn làm quá nhiều. Một lớp nên có một mục đích chính, và một khung nhìn nên chịu trách nhiệm cho xem và đó là nó. Để có chức năng mô hình hoặc kiểm soát và bạn mất cohesion, có thể tăng coupling và rủi ro tạo ra các đối tượng thần khó khăn nếu không thể gỡ lỗi hoặc mở rộng. Vì vậy, để đặt nó thẳng thắn, các lớp GUI hoặc chế độ xem của bạn nên không phải cũng là các lớp người nghe. Nói cách khác, không có lý do chính đáng và nhiều lý do xấu cho một lớp GUI cũng để thực hiện một giao diện người nghe.

Giải pháp tốt nhất: không có các lớp GUI của bạn triển khai người nghe.Thay vào đó, hãy sử dụng các lớp bên trong vô danh, hoặc các lớp bên trong riêng tư, hoặc nếu đủ phức tạp hoặc bạn dự đoán mở rộng và/hoặc sửa đổi mã của bạn trong tương lai, các lớp lắng nghe độc ​​lập.

+1

Đối với người nghe độc ​​lập, truy cập [* gói-riêng *] (http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) có thể hữu ích. – trashgod

+1

Các lớp bên trong vô danh không giải quyết vấn đề rò rỉ 'this', mặc dù, nếu các cá thể của chúng được tạo ra trong hàm tạo. Nó chỉ làm cho vấn đề khó phát hiện hơn từ bây giờ 'điều này' rò rỉ ngầm. –

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