В рамках разработки небольшого ScriptEngine я рефлексивно вызываю методы java. Вызов обработчиком сценариев дает мне имя объекта и массив аргументов. Чтобы вызвать метод, я попытался разрешить его с помощью вызова Class.getMethod (имя, типы аргументов).
Это, однако, работает только тогда, когда классы аргументов и ожидаемые методом классы совпадают.
Object o1 = new Object();
Object out = System.out;
//Works as System.out.println(Object) is defined
Method ms = out.getClass().getMethod("println",o1.getClass());
Object o2 = new Integer(4);
//Does not work as System.out.println(Integer) is not defined
Method mo = out.getClass().getMethod("println",o2.getClass());
Я хотел бы знать, существует ли "простой" способ получить правильный метод, если это возможно, с наиболее близким соответствием для типов аргументов, или я должен реализовать это сам.
Ближайшая подгонка будет:
Object o1 = new Integer(1);
Object o2 = new String("");
getMethod(name, o1.getClass())//println(Object)
getMethod(name, o2.getClass())//println(String)
Обновление:
Чтобы уточнить, что мне нужно:
Скриптовый движок - это небольшой проект, который я пишу в свободное время, поэтому нет никаких правил стрикта, которым я должен следовать. Поэтому я подумал, что выбор методов, вызываемых из Engine, так же, как компилятор java выбирает методы во время компиляции только с динамическим типом, а не статическим типом Object, будет работать (с автобоксом или без)
Это то, на что я впервые надеялся, что Class.getMethod () решит проблему. Но для Class.getMethod () требуются те же классы, что и для типов аргументов, которые объявляет метод, при использовании подкласса исключение метода не будет. Это может происходить по уважительным причинам, но делает метод бесполезным для меня, поскольку я заранее не знаю, какие типы аргументов подойдут.
Альтернативой было бы вызвать Class.getMethods () и выполнить итерацию по возвращенному массиву и попытаться найти подходящий метод. Однако это будет сложно, если я не просто захочу воспользоваться первым «хорошим» методом, с которым я столкнусь, поэтому я надеялся, что будет существующее решение, которое хотя бы обрабатывает:
- наиболее близкое соответствие: если arg.getClass () ==
подкласс и методы m (суперкласс),
m (подкласс), затем вызвать m (подкласс)
- переменные аргументы:
System.out.printf (String, String ...)
Было бы неплохо также поддерживать автобокс.
Если вызов не может быть разрешен, он может выдать исключение (ma (String, Object), ma (Object, String), args = String, String)
(Если вы сделали это до здесь, спасибо, что нашли время, чтобы прочитать это: -))