2011-11-23 31 views
40

Tôi nhận thấy rằng trong API phản chiếu Java có hai phương thức khác nhau để gọi các hàm tạo: phương thức getDeclaredConstructors/getConstructors. Mặc dù các tài liệu Java hơi khác nhau (getDeclaredConstructors dường như ngụ ý rằng nó trả về TẤT CẢ các nhà xây dựng, chứ không phải là các trình xây dựng công khai), nhưng không rõ lý do tại sao API hỗ trợ rõ ràng hai phương thức khác nhau này.Sự khác nhau giữa getDeclaredConstructors và getConstructors trong API lớp là gì?

Quan trọng hơn, tôi tự hỏi: khi nào một phương pháp sẽ thích hợp hơn với phương pháp khác nếu chúng ta đang gọi các lớp động? Ví dụ, mục đích của việc truy cập một hàm tạo riêng là gì?

Trả lời

46

getDeclaredConstructors (khi bạn muốn tất cả các nhà thầu)

Trả về một mảng các đối tượng Constructor phản ánh tất cả các nhà thầu công bố bởi lớp đại diện bởi đối tượng Class này. Đây là các truy cập công cộng, được bảo vệ, mặc định (gói) và các nhà xây dựng riêng.

getConstructors (khi bạn muốn chỉ public constructors)

Trả về một mảng chứa các đối tượng Constructor phản ánh tất cả các nhà thầu nào của lớp biểu diễn bởi đối tượng Class này.

Vì vậy, nhìn vào các tài liệu cho cả hai, tôi nghĩ rằng sự khác biệt là getConstructors lợi nhuận chỉ public nhà xây dựng trong khi getDeclaredConstructors trả về tất cả các nhà thầu (public, protected, mặc định gói) truy cập (và private)

Vì vậy, thật dễ dàng nếu bạn chỉ cần các nhà xây dựng public sau đó sử dụng getConstructors. Nếu không, nếu bạn cần tất cả các hàm tạo (không quan tâm đến công cụ sửa đổi truy cập của hàm tạo) thì hãy sử dụng getDeclaredConstructors.

+7

và bằng cách sử dụng constructor.setAccessible (true), bạn có thể gọi một cách phản ánh các hàm tạo riêng tư. – MeBigFatGuy

+0

Trong khi câu trả lời này là chính xác, có một chút báo trước. Trình biên dịch sẽ tự động cung cấp một hàm khởi tạo công khai mặc định (không có đối số) cho bất kỳ lớp nào không định nghĩa rõ ràng bất kỳ trình xây dựng nào. 'getConstructors' sẽ không trả về hàm tạo mặc định này nhưng' getDeclaredConstructors' sẽ làm. – neXus

3

Phương thức 'getDeclaredConstructors' trả về chỉ các Trình xây dựng được khai báo bên trong lớp. Phương thức 'getConstructors' cũng trả về các hàm tạo không được khai báo bên trong lớp nhưng được thừa kế từ các lớp siêu.

Vì vậy, nó phụ thuộc vào những gì bạn định làm. Không có cách tiếp cận đúng, nó thực sự phụ thuộc nếu bạn cũng cần các nhà xây dựng siêu.

+3

Điều này là sai. Các phương thức get * Constructors() làm _not_ hoạt động tương tự như phương thức get * Methods(). Cả hai đều chỉ tìm nạp các hàm tạo của lớp đã cho, bỏ qua các hàm tạo của các lớp bậc trên. Điều đó phù hợp với thực tế là khi khởi tạo một lớp, bạn phải sử dụng một trong các hàm tạo của nó, bạn không thể bỏ qua chúng và trực tiếp gọi một trong các hàm tạo của lớp cha của nó. Bạn có thể viết một vài lớp kiểm tra để kiểm tra điều này. (Tôi đã làm.) Vui lòng xóa câu trả lời sai lệch này. –

+3

Các nhà xây dựng không được kế thừa trong Java. –

3

Các phương pháp getDeclaredXX() tồn tại để thao tác các lớp theo cách không nhất thiết phải do nhà sản xuất của các lớp đó thiết kế. Lưu ý rằng có phương thức getDeclaredMethod() cho phép bạn gọi các phương thức riêng tư và phương thức getDeclaredField() cho phép bạn nhận/đặt các trường riêng tư.

Tôi không hoàn toàn chắc chắn về các trường hợp sử dụng "hợp pháp", nhưng điều này rõ ràng là hữu ích khi thực hiện những việc nhất định. Ngoài ra, họ phương thức này chỉ trả về những thứ được khai báo cụ thể trong lớp, không phải những thứ tồn tại trong lớp vì lớp cha.

Việc truy cập một hàm tạo riêng tư có thể hữu ích vì những lý do tương tự, tôi cho là vậy.

0

Tôi sử dụng getDeclaredConstructors để tạo một nhà máy của các lớp có hàm tạo riêng tư để tránh rằng "người dùng" của hệ thống của tôi có thể tạo các lớp này trực tiếp mà không cần sử dụng nhà máy. Tôi thấy phương pháp này khá hữu ích.

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