Нужно ли мне иметь дело с ситуацией, когда частные методы вызываются через рефлексию?

12

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

Например, если частный метод private DoSomething(int number)ожидает, что:

  • number является положительным ненулевым целым числом, и:
  • закрытая переменная string abcне является пустой и не пустой строкой,

и совершенно, безобразно терпит неудачу, если эти два условия не совпадают, я должен обработать эти сбои, даже если я знаю, что все методы в классе всегда будут присваивать непустое значение abcперед вызовом DoSomethingи передавать положительное ненулевое целое число этому метод?

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

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


¹ Поскольку класс правильно задокументирован, потому что существует достаточно модульных тестов, чтобы быть уверенным, что любой другой разработчик не сломает этот метод и т. Д.

Арсений Мурзенко
источник
смогут ли производные классы вызывать закрытые методы?
Энон

Ответы:

16

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

Та же проблема может возникнуть с другими языками, такими как C ++, где я видел такие вещи, как

#define private public

Таким образом, вы НЕ обязаны иметь дело с этими ситуациями, вызывающий должен знать лучше.

Otávio Décio
источник
3
Я видел, как люди приводили классы к (unsigned char *) и записывали непосредственно в смещение памяти переменной-члена, которую они хотят изменить. Мои глаза кровоточили.
Шон Д.
6
Я бы добавил, что по сути невозможно защитить ваш класс от опасного привилегированного кода. Если вам как-то удастся защитить себя от ненадлежащего использования рефлексии, тогда кто-то найдет другой способ испортить ваш день, возможно, просто переписав вашу память процесса напрямую. Защитное кодирование в конечном итоге достигает точки убывающей отдачи, и рефлексия уже далеко за этой точкой.
Аарона
5

Если кто-то использует рефлексию для вызова ваших личных методов, это признак того, что кто-то что-то делает не так. Либо он использует код способами, для которых он не предназначен, либо вы слишком много скрываете от внутренней работы и не обращаете внимания на API.

Но, похоже, вы еще не на этом этапе и просто пытаетесь быть упреждающим. Поэтому мое мнение таково: не беспокойтесь об этом. Частный метод должен рассматриваться как запретный; если кто-то сознательно нарушает эти ограничения, то это его проблема, если что-то взорвется.

Майк Баранчак
источник
0

Что ж, это всегда хорошая идея проверять нелокальные переменные перед их использованием, но в остальном я бы не беспокоился об этом. Как говорили другие, вы установили свои намерения, сделав метод в первую очередь приватным; любой, кто звонит из-за пределов вашего класса, не имеет никаких гарантий Работая на Java, я даже не размещаю комментарии javadoc в своих личных методах, потому что не хочу, чтобы другие разработчики даже знали, что они там есть.

TMN
источник