要在运行时java中动态传递class.getmethod参数吗
我想通过在运行时提供methodName从调用一个方法。我可以用下面的方法做要在运行时java中动态传递class.getmethod参数吗,java,reflection,overloading,Java,Reflection,Overloading,我想通过在运行时提供methodName从调用一个方法。我可以用下面的方法做 Method method = MyObject.class.getMethod("doSomething", String.class); Object returnValue = method.invoke(null, "parameter-value1"); 但是我想列出所有具有该方法名称和不同参数集的重载方法,让用户选择一个特定的重载方法并动态地传递这些参数 Method method = MyObject.
Method method = MyObject.class.getMethod("doSomething", String.class);
Object returnValue = method.invoke(null, "parameter-value1");
但是我想列出所有具有该方法名称和不同参数集的重载方法,让用户选择一个特定的重载方法并动态地传递这些参数
Method method = MyObject.class.getMethod("doSomething", String.class);
而不是硬编码String.class
假设我有两种方法,比如
methodName(String)
和重载方法
methodName(String, int)
我想让用户在运行时选择哪一个,并将该信息传递给该特定方法的getMethod
函数
如何执行此操作?我们调用了一个方法来按名称加载类的实例
问题是我们必须传递所需类的完全限定名(包括包的名称)。这意味着Class.forName(“字符串”)
不起作用。相反,我们需要将其称为Class.forName(“java.lang.String”)
我们可以有一个映射(或枚举)来保存那些类。由于我们希望用户进行协作,因此键将是String
s,并且通过查询类所具有的方法,结构将类似于map。然后检查参数信息。然后将其显示给用户。要调用该选项,我需要能够传递可变数量的参数类型,如getMethod(“doSomething”,String.class)或getMethod(“doSomething”,String.class,int.class);根据他们的选择。我必须在运行时动态地传递(String.class,int.class)这个信息。我该怎么做@AndrewTobilkoth非常感谢你,Andrew,但是如果我也要返回由调用的方法返回的对象,最简单的方法是什么?我不能从ifpresent块内部返回。@VivekKrishna最简单的方法是在ifpresent和get中打开ifpresent(更新了答案)@VivekKrishna我返回null
当我们无法继续时,您可能会抛出带有适当消息的异常
user > string
we < class java.util.String
Function<String, T> converter = (String s) -> T.convertFromString(s);
class Test {
// prints s once
public static void method(String s) {
System.out.println(s);
}
// prints s i times
public static void method(String s, int i) {
System.out.println(IntStream.rangeClosed(0, i - 1)
.mapToObj($ -> s)
.collect(Collectors.joining(" ")));
}
public static void main(String[] args) {
perform();
}
public static Object perform() {
final Scanner scanner = new Scanner(System.in);
// read the method name
final String methodName = scanner.nextLine();
final Method[] methods = Arrays.stream(Test.class.getDeclaredMethods())
.filter(m -> m.getName().endsWith(methodName) && !m.isSynthetic())
.toArray(Method[]::new);
// read the method parameter types in the format "type1 type2"
final String rawMethodParametersTypes = scanner.nextLine();
final SupportedType[] methodParameterTypes = Arrays.stream(rawMethodParametersTypes.split(" "))
.map(p -> SupportedType.valueOf(p.toUpperCase()))
.toArray(SupportedType[]::new);
final Optional<Method> selectedMethod = Arrays.stream(methods)
.filter(m -> Arrays.equals(Arrays.stream(methodParameterTypes)
.map(SupportedType::getType).toArray(Class<?>[]::new), m.getParameterTypes()))
.findAny();
if (!selectedMethod.isPresent()) {
return null;
}
final Method method = selectedMethod.get();
// read method arguments in the format "arg1 arg2"
final String rawMethodArgumentsLine = scanner.nextLine();
final String[] rawMethodArguments = rawMethodArgumentsLine.split(" ");
final int expectedLength = method.getParameterCount();
if (rawMethodArguments.length != expectedLength) {
return null;
}
Object[] methodArguments = new Object[expectedLength];
for (int i = 0; i < expectedLength; ++i) {
methodArguments[i] = methodParameterTypes[i].getConverter().apply(rawMethodArguments[i]);
}
try {
return method.invoke(null, methodArguments);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
@RequiredArgsConstructor
public enum SupportedType {
STRING(String.class, s -> s),
INT(int.class, Integer::valueOf);
@Getter
private final Class<?> type;
@Getter
private final Function<String, Object> converter;
}
> method
> string int
> hello 5
< hello hello hello hello hello
> method
> string
> hello
< hello