简体   繁体   English

通过将类名和方法名作为参数传递来运行java方法

[英]Run a java method by passing class name and method name as parameter

I am trying to make a program that executes a particular method when the class name and method name are passed as String parameter to the caller. 我正在尝试创建一个程序,当类名称和方法名称作为String参数传递给调用者时,执行特定的方法。 Consider the code below. 请考虑以下代码。 I have a class CarBean : 我有一个类CarBean:

public class CarBean {

    private String brand;
    private String color;

    /**
     * @return the brand
     */
    public String getBrand() {
        return brand;
    }

    /**
     * @param the brand to set
     */
    public void setBrand(String brand) {
        this.brand= brand;
    }

    /**
     * @return the color
     */
    public String getColor() {
        return color;
    }

    /**
     * @param the color to set
     */
    public void setColor(String color) {
        this.color= color;
    }

}

Now I want to run this via a method as below : 现在我想通过以下方法运行:

runTheMehod("CarBean","getColor");

The implementation of runTheMethod would be like this : runTheMethod的实现如下:

public runTheMethod(String className, String methodName){
try {
            Object carObj = Class.forName(className).newInstance();
            //What to do now???
        } catch (InstantiationException | IllegalAccessException
                | ClassNotFoundException e) {
            e.printStackTrace();
        }
}

I can get an object using the class name. 我可以使用类名获取一个对象。 Now I need to cast it to a CarBean object and then I can run its method. 现在我需要将它转换为CarBean对象然后我可以运行它的方法。 So wondering how to cast it at runtime as the classname would be different for each call. 所以想知道如何在运行时强制转换它,因为每个调用的类名都不同。 Also, can I check whether the class has specific method before I try call it? 另外,在尝试调用之前,我可以检查类是否具有特定方法吗?

Any suggestion on the problem would be appreciated. 任何关于这个问题的建议都将受到赞赏。 Also, I'm all ears to know if there is a better approach to do this. 此外,我很想知道是否有更好的方法来做到这一点。

What to do now??? 现在做什么???

You can now call the method on your carObj like this: 您现在可以像这样调用carObj上的方法:

Method method = carObj.getClass().getMethod(methodName);
method.invoke(carObj);

See also: 也可以看看:

Method.invoke Method.invoke

If all you are trying to do is call a method by name, you don't need to cast it to anything. 如果您要做的就是按名称调用方法,则无需将其强制转换为任何方法。 It is sufficient to use the Object with further reflection. 使用Object进一步反射就足够了。

See Class.getDeclaredMethod() , as in: 请参阅Class.getDeclaredMethod() ,如下所示:

Object carObj = ...;
Method method = carObj.getClass().getDeclaredMethod(methodName, ...);
Object retObj = method.invoke(carObj, ...);

Note that we don't care what type carObj actually is, although if you wanted to check you could always use instanceof or Class.isAssignableFrom or Class.isInstance . 请注意,我们并不关心carObj实际上是什么类型,但如果您想检查,您可以始终使用instanceofClass.isAssignableFromClass.isInstance

It is a bit weird, though, that you are instantiating a new object then calling one of its methods all in one go. 但是,有点奇怪的是,您实例化一个新对象,然后一次性调用其中一个方法。 That object goes away once your runTheMethod returns. 一旦你的runTheMethod返回,该对象就会消失。


By the way, it looks like you're just trying to get and set bean properties. 顺便说一句,看起来你只是想获取并设置bean属性。 You might want to have a look at Apache Commons BeanUtils instead, then your example becomes simply: 您可能想要查看Apache Commons BeanUtils ,然后您的示例变得简单:

CarBean bean = ...;
String color = (String)PropertyUtils.getSimpleProperty(bean, "color"); // calls getter.

I doubt you really need to do this. 我怀疑你真的需要这样做。 I suspect you have an XY Problem . 我怀疑你有一个XY问题 Your question is somewhat similar to asking whether Java has an eval function and the correct answer is similar : 您的问题有点类似于询问Java是否具有eval函数且正确答案是否相似

First ask yourself, where did these String come from? 首先问问自己,这些String来自哪里? Did another part of your program generate them, or was it input provided by the user? 您的程序的另一部分是否生成了它们,或者是用户提供的输入?

  • Another part of my program generated it : so, you want one part of your program to decide the kind of operation to perform, but not perform the operation, and a second part that performs the chosen operation. 我的程序的另一部分生成它 :因此,您希望程序的一部分决定要执行的操作类型,但不执行操作,以及执行所选操作的第二部分。 Instead of generating and then evaluating String s, use the Strategy , Command or Builder design pattern, as appropriate for your particular case. 而不是生成然后评估String ,而是根据您的具体情况使用策略命令构建器设计模式。

  • It is user input : the user could input anything , including class and method names that, when executed, could cause your program to misbehave, crash, expose information that should be secret, damage persistent information (such as the content of a database), and other such nastiness. 它是用户输入 :用户可以输入任何内容 ,包括类和方法名称,这些名称在执行时可能导致程序行为异常,崩溃,泄露应该保密的信息,破坏持久性信息(如数据库内容),和其他这样的肮脏。 The only way to prevent that would be to parse the String s and then either immediately execute the method on a successful parse, or have the parser create a Command object for later execution. 防止这种情况的唯一方法是解析String ,然后立即在成功的解析上执行该方法,或让解析器创建一个Command对象供以后执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM