Nhược điểm của sự phản ánh nói chung
Phản xạ khó hiểu hơn mã đường thẳng.
Theo kinh nghiệm của tôi, sự phản chiếu là một tính năng "cấp chuyên gia" trong Java. Tôi sẽ lập luận rằng hầu hết các lập trình viên không bao giờ sử dụng phản xạ một cách chủ động (tức là tiêu thụ các thư viện sử dụng sự phản chiếu không được tính). Điều đó làm cho mã sử dụng nó khó hiểu hơn đối với các lập trình viên này.
Mã phản chiếu không thể truy cập để phân tích tĩnh
Giả sử tôi có một getter getFoo
trong lớp và tôi muốn đổi tên nó thành getBar
. Nếu tôi không sử dụng phản xạ, tôi chỉ có thể tìm kiếm cơ sở mã getFoo
và sẽ tìm mọi nơi sử dụng getter để tôi có thể cập nhật nó, và ngay cả khi tôi bỏ lỡ một, trình biên dịch sẽ phàn nàn.
Nhưng nếu nơi sử dụng getter giống như callGetter("Foo")
và callGetter
thực hiện getClass().getMethod("get"+name).invoke(this)
, thì phương thức trên sẽ không tìm thấy nó và trình biên dịch sẽ không phàn nàn. Chỉ khi mã thực sự được thực thi, bạn sẽ nhận được a NoSuchMethodException
. Và hãy tưởng tượng nỗi đau mà bạn gặp phải nếu ngoại lệ đó (được theo dõi) bị nuốt bởi callGetter
vì "nó chỉ được sử dụng với các chuỗi mã hóa cứng, nó thực sự không thể xảy ra". (Không ai sẽ làm điều đó, ai đó có thể tranh luận? Ngoại trừ việc OP đã làm chính xác điều đó trong câu trả lời SO của anh ta. Người dùng của getter có thể, nếu họ may mắn, hãy chú ý đầu ra giao diện điều khiển của ngoại lệ bị bỏ qua.)
Mã phản chiếu không được kiểm tra kiểu bởi trình biên dịch
Đây về cơ bản là một điểm phụ lớn của ở trên. Mã phản ánh là tất cả về Object
. Các loại được kiểm tra tại thời gian chạy. Lỗi được phát hiện bởi các bài kiểm tra đơn vị, nhưng chỉ khi bạn có phạm vi bảo hiểm. ("Nó chỉ là một getter, tôi không cần phải kiểm tra nó.") Về cơ bản, bạn mất lợi thế khi sử dụng Java so với Python đã giúp bạn đạt được vị trí đầu tiên.
Mã phản chiếu không có sẵn để tối ưu hóa
Có thể không phải trên lý thuyết, nhưng trong thực tế, bạn sẽ không tìm thấy một JVM nội tuyến hoặc tạo bộ đệm nội tuyến cho Method.invoke
. Các cuộc gọi phương thức bình thường có sẵn để tối ưu hóa như vậy. Điều đó làm cho họ nhanh hơn rất nhiều.
Nói chung mã phản chiếu chỉ chậm
Việc tra cứu phương thức động và kiểm tra kiểu cần thiết cho mã phản chiếu chậm hơn so với các cuộc gọi phương thức thông thường. Nếu bạn biến chiếc getter một dòng giá rẻ đó thành một con thú phản chiếu, bạn có thể (tôi chưa đo được điều này) đang xem xét một số mức độ chậm lại.
Nhược điểm của getter / setter chung
Đó chỉ là một ý tưởng tồi, bởi vì lớp của bạn bây giờ không còn đóng gói nữa. Mỗi lĩnh vực nó có thể truy cập được. Bạn cũng có thể làm cho tất cả chúng công khai.