Digamos que tengo Method1 (void), Method2 (void) ...cómo llamar a un método Java usando un nombre de variable?
¿Hay alguna manera de elegir uno con una variable?
String MyVar=2;
MethodMyVar();
Digamos que tengo Method1 (void), Method2 (void) ...cómo llamar a un método Java usando un nombre de variable?
¿Hay alguna manera de elegir uno con una variable?
String MyVar=2;
MethodMyVar();
Uso reflexión:
Method method = WhateverYourClassIs.class.getDeclaredMethod("Method" + MyVar);
method.invoke();
+1, con la advertencia de que la reflexión puede ser lenta y el compilador ya no aplica la seguridad de tipo. – cHao
WRT su ejemplo, ¿esto no buscaría 'Método2' como el método? – javamonkey79
¿Qué dependencias tienen 'Método' y' Clase'? Estoy tratando de usar esto y me sale el error: 'método no estático getDeclaredMethod no se puede hacer referencia desde un contexto estático' – hellyale
podría utilizar el patrón de diseño Estrategia y un mapeo de la cadena que tiene al objeto estrategia concreta correspondiente. Este es el medio seguro y eficiente.
Por lo tanto, tiene un HashMap<String,SomeInterfaceYouWantToInvokeSuchAsRunnableWithPseudoClosures>
búsqueda.
por ejemplo, algo a lo largo de las líneas de:
final static YourType reciever = this;
HashMap<String,Runnable> m = new HashMap<String,Runnable> {{
add("a", new Runnable() {
@Override public void run() {
reciever.a();
}
});
....
}};
// but check for range validity, etc.
m.get("a").run()
También se puede utilizar la reflexión o "invertir" el problema y utilizar el polimorfismo
Corregí 'sobrescribir' a' @ Override' de Java, pero en realidad es innecesario. También las enumeraciones pueden ser útiles en algunos casos relacionados. La reflexión es, por supuesto, malvada. –
Hice solo una pequeña cantidad de investigación antes de preguntar esto, pero ¿por qué la reflexión es mala? Me parece muy poderoso, y parece que podría hacer que escribir un código sea más fácil. Honestamente, lo que escribiste arriba es la cosa más genial que he visto en toda la semana. Sin embargo, tengo una pregunta: ¿es su método de utilizar un hashmap mejor que los ejemplos de reflexión en este mismo hilo? – michaelsnowden
'add (" a ", ...' debe ser 'put (" a ", ...' –
Sólo a través de la reflexión. Consulte el paquete java.lang.reflect
.
Usted podría intentar algo como:
Method m = obj.getClass().getMethod("methodName" + MyVar);
m.invoke(obj);
Su código puede ser diferente si el método tiene parámetros y hay todo tipo de gestión de excepciones que falta.
Pero pregúntese si esto es realmente necesario? Puede cambiar algo sobre su diseño para evitar esto. El código de reflexión es difícil de entender y es más lento que simplemente llamar al obj.someMethod()
.
Buena suerte. Feliz Codificación.
No estoy seguro de cómo funciona la respuesta aceptada para method.invoke()
sin primer argumento de que el método estático es null
(el valor ficticio aún funciona). Según The Java™ Tutorials:
El primer argumento es la instancia de objeto en que el presente método en particular es que se invoca. (Si el método es estático, el primer argumento debería ser nulo.)
La siguiente muestra una completos ejemplos (Main.java), tanto para estático (por clase) VS no estático (por ejemplo), además de ejemplo adicional para método con argumento, importación clase es necesario, captura excepción, y también método de la superclase ejemplo.
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
class Love {
protected void Method4() {
System.out.println("calls super protected method by instance");
}
public void Method5() {
System.out.println("calls super public method by instance");
}
}
class Main extends Love {
static void Method2(int y) {
System.out.println("by class: " + y);
}
void Method3(String y) {
System.out.println(y);
}
public static void main(String[] args) {
String MyVar = "2";
String MyAnotherVar = "3";
String MySuperVar = "4";
String MySuperPublicMethodVar = "5";
Main m = new Main();
try {
Method method = Main.class.getDeclaredMethod("Method" + MyVar, int.class); //by class
Method anotherMethod = m.getClass().getDeclaredMethod("Method" + MyAnotherVar, String.class); //by instance
Method superMethod = m.getClass().getSuperclass().getDeclaredMethod("Method" + MySuperVar); //super method by instance, can be protected
Method superPublicMethod = m.getClass().getMethod("Method" + MySuperPublicMethodVar); //getMethod() require method defined with public, so even though sublcass calls super protected method will not works
try {
method.invoke(null, 10000);//by class
anotherMethod.invoke(m, "by instance"); //by instance
superMethod.invoke(m); //super method by instance
superPublicMethod.invoke(m); //super's public method by instance
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
Salida:
$ javac Main.java
$ java Main
by class: 10000
by instance
calls super protected method by instance
calls super public method by instance
$
Usted puede, pero ¿por qué quieres hacer esto? – jjnguy
Me encontré con un caso por esta vez, donde usar reflection + a HashMap tiene más sentido que un masivo si/else de comparaciones de cadenas y llamadas a métodos condicionales. – cHao
@cHao: seguramente un mejor esquema habría sido escribir una interfaz y usar un HashMap para almacenar objetos de esa interfaz como un análogo para funciones lambda. –