777 Stimmen

Wie rufe ich eine Java-Methode auf, wenn der Name der Methode als String angegeben ist?

Wenn ich zwei Variablen habe:

Object obj;
String methodName = "getName";

Ohne Kenntnis der Klasse der obj wie kann ich die Methode aufrufen, die durch methodName darauf?

Die aufgerufene Methode hat keine Parameter, und ein String Rückgabewert. Es ist ein Getter für eine Java-Bohne .

1079voto

Henrik Paul Punkte 65301

Aus der Hüfte heraus kodiert, würde es etwa so aussehen:

java.lang.reflect.Method method;
try {
  method = obj.getClass().getMethod(methodName, param1.class, param2.class, ..);
} catch (SecurityException e) { ... }
  catch (NoSuchMethodException e) { ... }

Die Parameter identifizieren die spezifische Methode, die Sie benötigen (wenn mehrere überladene Methoden verfügbar sind, wenn die Methode keine Argumente hat, geben Sie nur methodName ).

Dann rufen Sie diese Methode auf, indem Sie

try {
  method.invoke(obj, arg1, arg2,...);
} catch (IllegalArgumentException e) { ... }
  catch (IllegalAccessException e) { ... }
  catch (InvocationTargetException e) { ... }

Auch hier lassen Sie die Argumente in .invoke , wenn Sie keine haben. Aber ja. Lesen Sie über Java-Reflexion

233voto

Owen Punkte 2641

Utilice Methodenaufruf aus der Reflexion:

Class<?> c = Class.forName("class name");
Method method = c.getDeclaredMethod("method name", parameterTypes);
method.invoke(objectToInvokeOn, params);

Wo:

  • "class name" ist der Name der Klasse
  • objectToInvokeOn ist vom Typ Object und ist das Objekt, für das die Methode aufgerufen werden soll
  • "method name" ist der Name der Methode, die Sie aufrufen wollen
  • parameterTypes ist vom Typ Class[] und deklariert die Parameter, die die Methode benötigt
  • params ist vom Typ Object[] und deklariert die Parameter, die an die Methode übergeben werden sollen

130voto

silver Punkte 4971

Für diejenigen, die ein einfaches Codebeispiel in Java 7 suchen:

Dog Klasse:

package com.mypackage.bean;

public class Dog {
    private String name;
    private int age;

    public Dog() {
        // empty constructor
    }

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void printDog(String name, int age) {
        System.out.println(name + " is " + age + " year(s) old.");
    }
}

ReflectionDemo Klasse:

package com.mypackage.demo;

import java.lang.reflect.*;

public class ReflectionDemo {

    public static void main(String[] args) throws Exception {
        String dogClassName = "com.mypackage.bean.Dog";
        Class<?> dogClass = Class.forName(dogClassName); // convert string classname to class
        Object dog = dogClass.newInstance(); // invoke empty constructor

        String methodName = "";

        // with single parameter, return void
        methodName = "setName";
        Method setNameMethod = dog.getClass().getMethod(methodName, String.class);
        setNameMethod.invoke(dog, "Mishka"); // pass arg

        // without parameters, return string
        methodName = "getName";
        Method getNameMethod = dog.getClass().getMethod(methodName);
        String name = (String) getNameMethod.invoke(dog); // explicit cast

        // with multiple parameters
        methodName = "printDog";
        Class<?>[] paramTypes = {String.class, int.class};
        Method printDogMethod = dog.getClass().getMethod(methodName, paramTypes);
        printDogMethod.invoke(dog, name, 3); // pass args
    }
}

Sortie : Mishka is 3 year(s) old.


Sie können den Konstruktor auf diese Weise mit Parametern aufrufen:

Constructor<?> dogConstructor = dogClass.getConstructor(String.class, int.class);
Object dog = dogConstructor.newInstance("Hachiko", 10);

Alternativ können Sie auch die

String dogClassName = "com.mypackage.bean.Dog";
Class<?> dogClass = Class.forName(dogClassName);
Object dog = dogClass.newInstance();

und tun

Dog dog = new Dog();

Method method = Dog.class.getMethod(methodName, ...);
method.invoke(dog, ...);

Empfohlene Lektüre: Neue Klasseninstanzen erstellen

55voto

Petr Macek Punkte 1503

Die Methode kann auf diese Weise aufgerufen werden. Es gibt noch weitere Möglichkeiten (siehe Reflection-Api), aber dies ist die einfachste:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Assert;
import org.junit.Test;

public class ReflectionTest {

    private String methodName = "length";
    private String valueObject = "Some object";

    @Test
    public void testGetMethod() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
            IllegalAccessException, InvocationTargetException {
        Method m = valueObject.getClass().getMethod(methodName, new Class[] {});
        Object ret = m.invoke(valueObject, new Object[] {});
        Assert.assertEquals(11, ret);
    }

}

17voto

Tom Hawtin - tackline Punkte 142461

Erstens: nicht. Vermeiden Sie diese Art von Code. Es handelt sich in der Regel um wirklich schlechten Code, der zudem unsicher ist (siehe Abschnitt 6 von Sichere Kodierungsrichtlinien für das Java Programmiersprache, Version 2.0 ).

Wenn Sie es tun müssen, ziehen Sie java.beans der Reflection vor. Beans umhüllt Reflection und ermöglicht einen relativ sicheren und konventionellen Zugriff.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X