Есть ли практический способ ссылки на метод в классе безопасным для типов образом?
Прежде всего, отражение является типобезопасным. Просто он динамически типизирован, а не статически.
Итак, предполагая, что вы хотите статически типизированный эквивалент отражения, теоретический ответ таков: это невозможно. Учтите это:
Method m;
if (arbitraryFunction(obj)) {
obj.getClass().getDeclaredMethod("foo", ...);
} else {
obj.getClass().getDeclaredMethod("bar", ...);
}
Можем ли мы сделать это так, чтобы исключения типа времени выполнения не возникали? В общем случае НЕТ, поскольку это повлечет за собой доказательство того, что arbitraryFunction(obj)
заканчивается. (Это эквивалентно проблеме останова, которая в целом доказана неразрешимой и неразрешимой с использованием современной технологии доказательства теорем ... AFAIK.)
И я думаю, что этот дорожный блок применим к любому подходу, когда вы можете внедрить произвольный код Java в логику, которая используется для рефлексивного выбора метода из класса объекта.
На мой взгляд, в настоящее время единственным умеренно практичным подходом является замена отражающего кода чем-то, что генерирует и компилирует исходный код Java. Если этот процесс происходит до того, как вы «запустите» приложение, вы выполнили требование статической безопасности типов.
Я больше спрашивал об отражении, в котором результат всегда одинаков. И.Е. Person.class.getMethod("getPhoneNumber", null)
всегда возвращает один и тот же метод, и его можно полностью разрешить во время компиляции.
Что произойдет, если после компиляции класса, содержащего этот код, вы измените Person
для удаления метода getPhoneNumber
?
Единственный способ убедиться, что вы можете разрешить getPhoneNumber
рефлексивно, - это если вы как-то предотвратите изменение Person
. Но вы не можете сделать это в Java. Привязка классов во время выполнения является фундаментальной частью языка.
(Для записи, если бы вы сделали это для метода, который вы вызывали неотражающим образом, вы бы получили IncompatibleClassChangeError
некоторого вида, когда два класса были загружены ...)