2011-08-19 33 views
11

Đây là một bài tập học thuật (từ chối trách nhiệm).Hiệu suất thời gian chạy phản chiếu Java

Tôi đang xây dựng một ứng dụng sẽ có lợi nhuận từ càng nhanh càng tốt vì nó sẽ cạnh tranh với những người khác.

Tôi biết rằng việc khai báo một lớp bằng cách sử dụng sự phản chiếu (ví dụ bên dưới) sẽ phải chịu một hình phạt lớn như trái ngược với tuyên bố tiêu chuẩn.

Class mDefinition = Class.forName("MySpecialClassString"); 
Constructor mConstructor = mDefinition.getConstructor(new Class[]{MySpecialClass.class}); 
myClass = (MySpecialClass) mConstructor.newInstance(this); 

Tuy nhiên, sau khi tuyên bố myClass nếu tôi sử dụng nó trong một thời trang tiêu chuẩn myClass.myMethod()sẽ Tôi cũng bị heo hiệu suất hoặc nó sẽ giống như thể tôi đã tuyên bố các lớp trong một thời trang tiêu chuẩn?

Trả lời

14

Sẽ có hình phạt về hiệu suất khi bạn khởi tạo đối tượng lần đầu tiên. Một khi lớp được nạp, nó giống như khi nó được khởi tạo bình thường, và sẽ không có thêm hình phạt nào về hiệu suất.

Đi xa hơn, nếu bạn gọi các phương thức sử dụng sự phản chiếu, sẽ có một hình phạt về hiệu suất trong khoảng mười lăm lần (mặc định bằng Java), sau đó cuộc gọi được ghi lại sẽ được JVM ghi lại chính xác như được biên dịch tĩnh gọi điện. Do đó, thậm chí nhiều lần phản ánh các cuộc gọi phương thức sẽ không làm giảm hiệu suất, một khi bytecode đã được biên dịch lại bởi JVM.

Xem hai liên kết này để biết thêm thông tin về rằng:

+0

thks cho mô tả khá chi tiết và tài liệu bổ sung. Thực sự tỏ ra hữu ích trong những ngày cuối cùng này. – Frankie

7

Khi lớp học đã được tải, bạn sẽ ổn. Chi phí gọi là một phương thức đại diện cho lớp, vv Các phương thức gọi theo kiểu tiêu chuẩn sẽ ổn, tuy nhiên nếu bạn bắt đầu tìm kiếm các phương thức theo tên hoặc chữ ký, nó sẽ phải trả thêm phí.

+1

+1 đồng ý - không nên có chi phí rất lớn cho một tra cứu động one-shot. –

+0

@Chris Tôi đã chạy một số thử nghiệm và bạn đã đúng với các giả định của mình. Cảm ơn bạn đã thanh toán trước điều này. – Frankie

2

Câu trả lời của Chris Thompson là trên nhãn hiệu. Tuy nhiên tôi đang bối rối bởi ví dụ mã của bạn.

này sẽ tự động tải các lớp:

Class mDefinition = Class.forName("MySpecialClassString"); 

này sẽ nhận được một Contructor cho lớp học của bạn, trong đó có một thể hiện của cùng một lớp như một cuộc tranh cãi. Cũng lưu ý rằng bạn đang truy cập lớp tại thời điểm biên dịch với MySpecialClass.class:

Constructor mConstructor = mDefinition.getConstructor(new Class[]{MySpecialClass.class}); 

này được instantiating một MySpecialClass bằng cách thông qua this vào constructor:

myClass = (MySpecialClass) mConstructor.newInstance(this); 

Dựa trên lập luận constructor, đó có nghĩa là chúng tôi đang trong một phương pháp thể hiện của MySpecialClass? Rất bối rối.

EDIT: Đây là gần gũi hơn với những gì tôi dự kiến ​​sẽ có để xem:

Class<?> mDefinition = Class.forName("MySpecialClassString"); 

//constructor apparently takes this as argument 
Class<?> constructorArgType = this.getClass(); //could be ThisClassName.class 

Constructor<?> mConstructor = mDefinition.getConstructor(constructorArgType); 

MySpecialInterface mySpecialInstance = (MySpecialInterface)mConstructor.newInstance(this); 

nơi MySpecialInterface là một giao diện sử dụng để tương tác với các lớp được nạp tự động của bạn:

interface MySpecialInterface { 
    //methods used to interface with dynamically loaded classes 
} 

Dù sao xin vui lòng cho tôi biết nếu tôi hiểu lầm hoặc tắt cơ sở ở đây.

+0

có lẽ bạn đã đúng vì tôi mới bắt đầu sử dụng sự phản chiếu ngay bây giờ. Hãy để tôi giới thiệu tóm tắt về cách thức hoạt động của hệ thống. Chúng tôi đã có ba lớp ClassA_interaction, ClassB_object và ClassC_logic ... ClassA_interaction khởi chạy một số ClassB_object và cung cấp chúng với các vị trí. Mỗi ClassB_object khởi chạy một phản chiếu sử dụng ClassC_logic. ClassC_logic là nguồn cấp dữ liệu với 'this' (ClassB_object) vì chúng phải gọi các hàm tồn tại trên ClassB_object. Nó có thể lộn xộn nhưng hoạt động. Bạn có gợi ý tôi có cách tiếp cận khác không? Thks dành thời gian để nhìn vào mã của tôi. – Frankie

+0

Tôi phải nói rằng tôi chưa đích thân làm việc với tải lớp động, đó là lý do tại sao tôi muốn xác nhận từ ai đó. Nhưng, sự hiểu biết của tôi là nếu bạn trực tiếp tham chiếu một lớp trong mã của bạn hoặc thậm chí có quyền truy cập vào lớp đó tại thời gian biên dịch, không có điểm nào để tải động nó. Tuy nhiên, nó sẽ có ý nghĩa nếu bạn có một 'Foo' được tải tĩnh mà là một lớp trừu tượng hoặc giao diện, và các lớp được nạp động của bạn mở rộng/triển khai thực hiện' Foo'. Bằng cách đó, sau khi bạn nạp động một lớp và khởi tạo nó, bạn có thể đưa nó vào 'Foo' và tương tác với nó mà không cần phản ánh thêm. –

+0

Tất nhiên, 'Foo' cần phải biết mọi thứ bạn sẽ muốn làm với các lớp được nạp động này, dưới dạng khai báo phương thức trừu tượng/giao diện. –

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