Như @Voo nói,
câu hỏi của bạn là về gọi một phương thức ảo trên một đối tượng đã hoàn toàn xây dựng. Các downfalls nổi tiếng gọi phương pháp ảo trên đối tượng xây dựng được nổi tiếng, nhưng không áp dụng ở đây
Từ Effective Java 2nd Edition, khoản 17: Thiết kế và tài liệu cho các thừa kế, nếu không cấm nó :
Có một vài hạn chế khác mà lớp học phải tuân thủ để cho phép thừa kế . Các nhà xây dựng không được gọi các phương pháp có thể ghi đè, trực tiếp hoặc gián tiếp. Nếu bạn vi phạm quy tắc này, lỗi chương trình sẽ kết quả là . Trình tạo lớp bậc trên chạy trước lớp con của lớp con , vì vậy phương thức ghi đè trong lớp con sẽ được gọi trước khi hàm tạo lớp con chạy. Nếu phương pháp ghi đè phụ thuộc vào bất kỳ khởi tạo nào được thực hiện bởi hàm tạo lớp con, phương thức sẽ không hoạt động như mong đợi.
Gọi phương thức có thể ghi đè trong khi xây dựng đối tượng có thể dẫn đến việc sử dụng dữ liệu chưa được khởi tạo, dẫn đến ngoại lệ thời gian chạy hoặc kết quả không lường trước được.
Constructors phải gọi chỉ phương pháp mà là cuối cùng hay tin
Bạn có thể sử dụng phương pháp nhà máy tĩnh để giải quyết vấn đề mà bạn phải tạo các đối tượng của bạn từ Bar class
.
Effective Java, khoản 1: Xem xét các phương pháp nhà máy tĩnh thay vì nhà xây dựng
Cách bình thường đối với một lớp học để cho phép một khách hàng để có được một thể hiện của chính nó là để cung cấp một constructor công cộng. Có một kỹ thuật khác là nên là một phần của bộ công cụ của mỗi lập trình viên. Một lớp có thể cung cấp phương thức nhà máy tĩnh công khai, chỉ đơn giản là phương thức tĩnh trả về một thể hiện của lớp.
Vì vậy, bạn đi đến có giao diện:
public interface Foo {
void doFoo();
}
và thực hiện:
public class FooImpl implements Foo {
@Override
public void doFoo() {
//.. Do important code
}
}
Để tạo lớp học của bạn với phương pháp nhà máy của bạn, bạn có thể làm việc bằng cách này:
Sử dụng giao diện để xác định biến lớp học của bạn private Foo fi
thay vì private FooImpl fi
, sử dụng giao diện trên các loại bê tông là chìa khóa để đóng gói tốt và cho khớp nối lỏng mã của bạn.
Đặt hàm tạo mặc định của bạn ở chế độ riêng tư để ngăn việc khởi tạo lớp học của bạn bên ngoài.
Bar tin() {// Ngăn chặn instantiation }
Hủy bỏ tất cả các cuộc gọi đến ghi đè lên các phương pháp được hiện diện trong constructor của bạn.
Tạo phương thức tĩnh của bạn
Cuối cùng bạn sẽ có được một lớp Bar
với một phương pháp nhà máy như:
public class Bar {
private Foo fi;
private Bar() {// Prevents instantiation
fi = new FooImpl();
}
public static Bar createBar() {
Bar newBar = new Bar();
newBar.fi.doFoo();
return newBar;
}
}
My Boss nói: “những lời cảnh báo Sonar khoảng triệu chứng, không phải về bệnh . Tốt nhất là khi bạn có thể điều trị căn bệnh này. ”
Mã bạn đã hiển thị đang gọi phương thức ghi đè * sau * được gọi là hàm tạo, không phải * từ * hàm tạo, phải không? Hay tôi đang thiếu một cái gì đó? – NPE
Hiển thị mã thực sự ức chế cảnh báo có thể là một ý tưởng tuyệt vời .. – Voo
aix- Nó đang nâng cao thông điệp vì Bar đang gọi fi.doFoo() bên trong hàm tạo của Bar. Voo - Mã quá dài để sao chép/dán. Đây là một ví dụ được cắt tỉa về những gì đang diễn ra – user973479