Java: разрешение метода во время выполнения - PullRequest
15 голосов
/ 16 мая 2011

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

.«Простой» способ выбора метода - это когда вы знаете точные типы всех аргументов, и в этот момент вы можете использовать Class.getDeclaredMethod(String name, Class[] parameterTypes).Может быть, вам нужно проверить доступность метода и суперклассы / суперинтерфейсы класса.

Но это не распространяется ни на один из следующих случаев, поэтому это бесполезно:

  • упаковка / распаковкапримитивы
  • подтипы
  • varargs
  • пустой аргумент (может быть любым типом, если интерпретатор не знает иначе; во время компиляции любая неоднозначность будет устранена путем приведения нулевого значения ккласс / интерфейс)
  • преобразование примитивного типа (не является частью Java, но допустимо в контексте языков - например, Rhino Javascript, где все числа с плавающей запятой, поэтому код Java может принимать intно вызывающий передает число, которое является либо int, либо double)

(краткий пример первых трех см. ниже)

Так что теперь яЯ должен написать свою собственную библиотеку разрешения методов ...

Есть ли какая-нибудь известная библиотека фреймворков, чтобы помочь в этом?

package com.example.test.reflect;

import java.lang.reflect.Method;

public class MethodResolutionTest {
    public void compute(int i)              { /* implementation... */ }
    public void compute(Long l)             { /* implementation... */ }
    public void compute(Object obj)         { /* implementation... */ }
    public void compute(String... strings)  { /* implementation... */ }

    public static void main(String[] args) {
        Class<?> cl = MethodResolutionTest.class;

        /* these succeed */
        findAndPrintMethod(cl, "compute", int.class);
        findAndPrintMethod(cl, "compute", Long.class);
        findAndPrintMethod(cl, "compute", Object.class);
        findAndPrintMethod(cl, "compute", String[].class);

        /* these fail */
        findAndPrintMethod(cl, "compute", Integer.class);
        findAndPrintMethod(cl, "compute", long.class);
        findAndPrintMethod(cl, "compute", MethodResolutionTest.class);
        findAndPrintMethod(cl, "compute", String.class, String.class);
    }
    private static void findAndPrintMethod(Class<?> objectClass, 
            String methodName, Class<?>... parameterTypes) 
    {
        try {
            Method method = findMethod(objectClass, methodName, 
                   parameterTypes);
            System.out.println(method.toString());
        }
        catch (SecurityException e) {
            e.printStackTrace();
        }
        catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
    private static Method findMethod(Class<?> objectClass, 
            String methodName, Class<?>[] parameterTypes) 
        throws SecurityException, NoSuchMethodException 
    {
        return objectClass.getDeclaredMethod(methodName, parameterTypes);
    }
}

Ответы [ 4 ]

3 голосов
/ 17 мая 2011

Вы можете прочитать это сообщение в блоге и проверить ClassMate . Это должно сделать большую часть безобразной работы за вас.

2 голосов
/ 17 мая 2011

Beanutils Commons имеют эту функцию для поиска подходящих методов: getMatchingAccessibleMethod

Он работает с примитивными типами, но, как говорится в документации, он несколько неопределенный.

0 голосов
/ 20 мая 2011

Один из пользователей на guava-обсуждение рекомендовал мне посмотреть Зеркало библиотеки .

К сожалению, он не поддерживает разрешение перегрузки, по крайней мере, в настоящее время.

0 голосов
/ 17 мая 2011

У меня был некоторый успех с MVEL и свойствами, но я не могу вспомнить, может ли он отправлять вызовы методов.

Однако, вы, возможно, ищете другой язык полностью.Учитывая природу проблемы, я предлагаю взглянуть на Groovy, который очень четко интегрируется с Java.

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