2008-10-12 11 views
82

Ryan Delucchi hỏi here ở comment # 3 vào câu trả lời Tom Hawtin 's:Tại sao Class.newInstance() "ác"?

tại sao Class.newInstance() "ác"?

này để đáp ứng với các mẫu mã:

// Avoid Class.newInstance, for it is evil. 
Constructor<? extends Runnable> ctor = runClass.getConstructor(); 
Runnable doRun = ctor.newInstance(); 

như vậy, tại sao nó ác?

+9

Thực ra nhìn thấy câu trả lời cho câu hỏi này: người ta có thể nói điều này về nhiều cách sử dụng phản chiếu ... không chỉ Class.newInstance(). Vì vậy, điều này thực sự là một quan sát chung rằng "phản ánh đánh bại kiểm tra thời gian biên dịch" ... mà thường là điểm phản ánh. –

+23

Trẻ em những ngày này, Oh yea họ ném xung quanh từ "EVIL" nhưng họ chưa bao giờ thậm chí SEEN một chương trình COBOL hoặc FORTRAN! Bạn muốn "EVIL" hãy xem chương trình FORTRAN 20 năm đã được chuyển từ dự án đến dự án bởi tinker's với một nền mô phỏng và không có CS ảnh hưởng gì đến vậy! Bây giờ là "EVIL!" – NoMoreZealots

+0

Xem thêm http://stackoverflow.com/q/36272566/3888450 –

Trả lời

71

Java API documentation giải thích tại sao (http://java.sun.com/javase/6/docs/api/java/lang/Class.html#newInstance()):

Lưu ý rằng phương pháp này truyền bất kỳ ngoại lệ ném ra bởi các nhà xây dựng nullary, trong đó có một ngoại lệ kiểm tra. Sử dụng phương pháp này có hiệu quả bỏ qua việc kiểm tra ngoại lệ biên dịch thời gian mà nếu không sẽ được thực hiện bởi trình biên dịch. Phương thức Constructor.newInstance tránh được vấn đề này bằng cách gói bất kỳ ngoại lệ nào được ném bởi hàm tạo trong một (kiểm tra) InvocationTargetException.

Nói cách khác, nó có thể đánh bại hệ thống ngoại lệ đã kiểm tra.

+11

Đây chính là bản chất của sự phản chiếu nói chung ... không hoàn toàn cụ thể đối với Constructor.newInstance(). –

+23

@Ryan: Điều đó không đúng; tất cả các phương thức gọi dựa trên sự phản chiếu khác ném một ngoại lệ đã kiểm tra được gọi là 'InvocationTargetException' kết thúc tốt đẹp bất kỳ ném ném nào bằng phương thức được gọi. 'Class.newInstance' sẽ không làm điều đó --- nó sẽ ném trực tiếp ngoại lệ đã kiểm tra. Nhược điểm là javac sẽ không cho phép bạn cố gắng nắm bắt những ngoại lệ đó, bởi vì 'Class.newInstance' không được khai báo để ném chúng. –

+1

Huh, tôi đã sửa chữa :-) Cảm ơn. –

18

Thêm một lý do:

IDE hiện đại cho phép bạn tìm cách dùng lớp - nó giúp trong tái cấu trúc, nếu bạn và IDE của bạn biết những gì đang sử dụng lớp mà bạn dự định thay đổi.

Khi bạn không sử dụng rõ ràng hàm tạo, nhưng sử dụng Class.newInstance() thay vào đó, bạn có nguy cơ không tìm thấy sử dụng đó trong quá trình tái cấu trúc và vấn đề này sẽ không tự biểu hiện khi bạn biên dịch.

+15

Cũng là một dấu hiệu chung của việc sử dụng sự phản chiếu. –