Метод, принимающий что-либо и сохраняющий подпись?

#java #reflection

#ява #отражение #java — язык

Вопрос:

Вы можете определить метод, который будет принимать все, что угодно (Object... arguments) но, если вы вызовете его с помощью ("A", "B") и (["A", "B"]) , значение arguments будет таким же ["A", "B"] , т. Е. исходная подпись будет потеряна.

Есть ли какой-нибудь способ сохранить это?

P.S. Зачем мне это нужно:

Запомнить вызываемый метод и аргументы и позже ответить на него с помощью отражения. Пример, когда он ломается:

Есть объект с методом, который я хотел бы вызвать позже:

 MyObj {
  myMeth (String[] array) {...}
}
myObj = new MyObj()
  

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

 callLater(myObj, "myMeth", ["A", "B"])
  

Он запоминает это, и пользователи пытаются найти фактический метод и вызвать его.
И это не удается, потому что оригинальная подпись потерялась, и вместо (String[]) нее пытаются найти (String, String) .

Комментарии:

1. Если я правильно помню, в reflection переменные аргументы всегда обрабатываются как массивы. Таким образом, вам нужно иметь возможность искать Object[] в качестве параметров метода

2. «Оригинальная подпись будет утеряна» ничего не значит. Это не потеряно. Он просто вызывается с помощью двух разных списков аргументов, в чем и заключается вся идея. Непонятно, о чем на самом деле ваш вопрос.

Ответ №1:

Такого рода двусмысленность устраняется на стороне вызывающей стороны с помощью приведений. В этом случае вы должны сначала привести массив к (Object) , чтобы он обрабатывался как аргумент varargs. например, передать массив в качестве одного аргумента:

 callLater(myObj, "myMeth", (Object) new String[] {"A", "B"});
  

Для передачи двух аргументов:

 callLater(myObj, "myMeth", (Object[]) new String[] {"A", "B"});
  

или просто:

 callLater(myObj, "myMeth", "A", "B");
  

Комментарии:

1. Спасибо, но это не очень удобно, есть ли способ получше? Я хотел бы использовать его как DSL и сохранить его простым и приятным.

2. Если вы хотите что-то «более приятное», вам придется предоставить две версии (названные по-разному; не могут быть перегружены) вашего метода: одну, которая принимает varargs, и другую, которая принимает массив напрямую.

3. Пробовал, компилятор запрещает иметь два метода (Object... data) и (Object[] data) с одинаковым именем.

4. Да, вот почему я сказал «названный по-другому». 😀