Производительность отражения Java во время выполнения - PullRequest
11 голосов
/ 19 августа 2011

Это академическое упражнение (отказ от ответственности).

Я создаю приложение, которое выиграет от того, что будет как можно быстрее , так как оно будет конкурировать с другими.

Я знаю, что объявление класса с использованием отражения (пример ниже) понесет огромный штраф в отличие от стандартного объявления.

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

Однако после объявления myClass, если я использую его стандартным способомmyClass.myMethod() Я также буду страдать от повышения производительности или это будет так же, как если бы я объявил класс стандартным способом?

Ответы [ 3 ]

14 голосов
/ 19 августа 2011

Производительность будет снижена при первом создании объекта. Как только класс загружен, он такой же, как если бы он был создан обычным образом, и больше не будет никакого снижения производительности.

В дальнейшем, если вы вызываете методы с использованием отражения, производительность снижается примерно пятнадцать раз (по умолчанию в Java), после чего отраженный вызов будет переписан JVM, чтобы он был точно таким же, как статически скомпилированный вызов. , Поэтому даже неоднократно отраженные вызовы методов не приведут к снижению производительности, как только этот байт-код будет перекомпилирован JVM.

См. Эти две ссылки для получения дополнительной информации об этом:

7 голосов
/ 19 августа 2011

Как только класс будет загружен, у вас все будет хорошо. Издержки связаны с проверкой структур времени выполнения, представляющих класс и т. Д. Вызов методов стандартным способом должен выполняться, однако, если вы начнете искать методы по имени или сигнатуре, это повлечет за собой дополнительные издержки.

2 голосов
/ 19 августа 2011

Крис Томпсон ответил на вопрос.Однако я смущен вашим примером кода.

это будет динамически загружать класс:

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

Это получит Contructor для вашего класса, который принимает экземпляр того же самогокласс в качестве аргумента.Также обратите внимание, что вы получаете доступ к классу во время компиляции с помощью MySpecialClass.class:

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

Это создает экземпляр MySpecialClass, передав this в конструктор:

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

Исходя из аргумента конструктора, означает ли это, что мы находимся в методе экземпляра MySpecialClass?Очень запутанный.

РЕДАКТИРОВАТЬ: Это ближе к тому, что я ожидал увидеть:

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);

, где MySpecialInterface - интерфейс, используемый для взаимодействия с вашимдинамически загружаемые классы:

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

В любом случае, пожалуйста, дайте мне знать, если я здесь недопонимаю или не в курсе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...