当前位置:  开发笔记 > 编程语言 > 正文

将方法名称作为字符串给出时,如何调用Java方法?

如何解决《将方法名称作为字符串给出时,如何调用Java方法?》经验,为你挑选了13个好方法。

如果我有两个变量:

Object obj;
String methodName = "getName";

在不知道类的情况下obj,如何调用其上标识的方法methodName

被调用的方法没有参数和String返回值.它是Java bean的getter.



1> Henrik Paul..:

从臀部编码,它将是这样的:

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

参数标识了您需要的非常具体的方法(如果有多个重载可用,如果方法没有参数,则只给出methodName).

然后通过调用调用该方法

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

再次,.invoke如果你没有参数,请省略参数.但是,是的.阅读Java Reflection


不公平-1.亨里克可能并不主张压缩异常,也没有为他们写任何东西,因为他只是想证明反思.
另外一个用于显示一些潜在的例外.如果我写了这个,那将是...... catch(例外e){...
对Java使用类型擦除这一事实感到有点不安,但知道至少它有反射让我再次振作起来:D现在,在Java 8中使用lambdas语言实际上正在加速现代开发.现在唯一缺少的是对getter和setter的本机支持,或者在C#中已知的属性.
@DeaMon1 Java方法不使用"退出代码",但如果方法返回任何内容,`invoke`将返回它返回的内容.如果运行该方法时发生异常,则异常将包含在`InvocationTargetException`中.

2> Owen..:

使用反射中的方法调用:

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

哪里:

"class name" 是类的名称

objectToInvokeOn 是Object类型,是要调用方法的对象

"method name" 是您要调用的方法的名称

parameterTypes是类型Class[]并声明方法采用的参数

params是类型Object[]并声明要传递给方法的参数


错误.是的,getDeclaredMethod可以使用私有和受保护的方法.但是:它不适用于超类中定义的方法(继承方法).所以,这很大程度上取决于你想做什么.在许多情况下,无论定义方法的确切类如何,您都希望它能够工作.

3> silver..:

对于那些想要在Java 7中使用直接代码示例的人:

Dog 类:

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 类:

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
    }
}

输出: Mishka is 3 year(s) old.


您可以通过以下方式调用带有参数的构造函数:

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

或者,您可以删除

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

并做

Dog dog = new Dog();

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

建议阅读: 创建新类实例



4> Petr Macek..:

可以像这样调用该方法.还有更多的可能性(检查反射api),但这是最简单的:

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);
    }



}


+1唯一的答案,认识到OP在他的问题中指定了"无参数"(因为它也是我所寻找的).

5> Tom Hawtin -..:

首先,不要.避免使用这种代码.它往往是非常糟糕的代码和不安全的(参见Java编程语言安全编码指南第2节,版本2.0).

如果你必须这样做,那就选择java.beans来反思.豆包裹反射允许相对安全和传统的访问.


我不同意.编写这样的代码以保证安全是非常容易的,我已经用多种语言编写了这些代码.例如,可以创建一组允许的方法,并且只有在方法名称在集合中时才允许调用方法.更安全(但仍然简单的骨头)将每个允许的方法限制为特定状态,并且不允许调用该方法,除非线程/接口/用户/任何符合这样的标准.

6> VonC..:

为了完成我同事的答案,您可能需要密切关注:

静态或实例调用(在一种情况下,您不需要该类的实例,在另一种情况下,您可能需要依赖现有的默认构造函数,可能存在也可能不存在)

公共或非公共方法调用(对于后者,您需要在doPrivileged块中的方法上调用setAccessible,其他findbugs将不满意)

如果你想要抛弃大量的java系统异常(因此下面的代码中的CCException),则封装成一个更易于管理的应用程序异常

这是一个旧的java1.4代码,它考虑了这些点:

/**
 * Allow for instance call, avoiding certain class circular dependencies. 
* Calls even private method if java Security allows it. * @param aninstance instance on which method is invoked (if null, static call) * @param classname name of the class containing the method * (can be null - ignored, actually - if instance if provided, must be provided if static call) * @param amethodname name of the method to invoke * @param parameterTypes array of Classes * @param parameters array of Object * @return resulting Object * @throws CCException if any problem */ public static Object reflectionCall(final Object aninstance, final String classname, final String amethodname, final Class[] parameterTypes, final Object[] parameters) throws CCException { Object res;// = null; try { Class aclass;// = null; if(aninstance == null) { aclass = Class.forName(classname); } else { aclass = aninstance.getClass(); } //Class[] parameterTypes = new Class[]{String[].class}; final Method amethod = aclass.getDeclaredMethod(amethodname, parameterTypes); AccessController.doPrivileged(new PrivilegedAction() { public Object run() { amethod.setAccessible(true); return null; // nothing to return } }); res = amethod.invoke(aninstance, parameters); } catch (final ClassNotFoundException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+CLASS, e); } catch (final SecurityException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_SECURITY_ISSUE, e); } catch (final NoSuchMethodException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_NOT_FOUND, e); } catch (final IllegalArgumentException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_ILLEGAL_ARGUMENTS+String.valueOf(parameters)+GenericConstants.CLOSING_ROUND_BRACKET, e); } catch (final IllegalAccessException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_ACCESS_RESTRICTION, e); } catch (final InvocationTargetException e) { throw new CCException.Error(PROBLEM_TO_ACCESS+classname+GenericConstants.HASH_DIESE+ amethodname + METHOD_INVOCATION_ISSUE, e); } return res; }



7> chickeninabi..:
Object obj;

Method method = obj.getClass().getMethod("methodName", null);

method.invoke(obj, null);


有一个错误.obj必须初始化.

8> anujin..:
//Step1 - Using string funClass to convert to class
String funClass = "package.myclass";
Class c = Class.forName(funClass);

//Step2 - instantiate an object of the class abov
Object o = c.newInstance();
//Prepare array of the arguments that your function accepts, lets say only one string here
Class[] paramTypes = new Class[1];
paramTypes[0]=String.class;
String methodName = "mymethod";
//Instantiate an object of type method that returns you method name
 Method m = c.getDeclaredMethod(methodName, paramTypes);
//invoke method with actual params
m.invoke(o, "testparam");



9> Christian Ul..:

如果多次执行调用,则可以使用Java 7中引入的新方法句柄.这里我们将返回一个返回String的方法:

Object obj = new Point( 100, 200 );
String methodName = "toString";  
Class resultType = String.class;

MethodType mt = MethodType.methodType( resultType );
MethodHandle methodHandle = MethodHandles.lookup().findVirtual( obj.getClass(), methodName, mt );
String result = resultType.cast( methodHandle.invoke( obj ) );

System.out.println( result );  // java.awt.Point[x=100,y=200]



10> zxcv..:

这听起来像Java Reflection包可以使用的东西.

http://java.sun.com/developer/technicalArticles/ALT/Reflection/index.html

特别是在名称调用方法下:

import java.lang.reflect.*;

public class method2 {
  public int add(int a, int b)
  {
     return a + b;
  }

  public static void main(String args[])
  {
     try {
       Class cls = Class.forName("method2");
       Class partypes[] = new Class[2];
        partypes[0] = Integer.TYPE;
        partypes[1] = Integer.TYPE;
        Method meth = cls.getMethod(
          "add", partypes);
        method2 methobj = new method2();
        Object arglist[] = new Object[2];
        arglist[0] = new Integer(37);
        arglist[1] = new Integer(47);
        Object retobj 
          = meth.invoke(methobj, arglist);
        Integer retval = (Integer)retobj;
        System.out.println(retval.intValue());
     }
     catch (Throwable e) {
        System.err.println(e);
     }
  }
}



11> Rahul Karank..:

请参考以下代码可能对您有所帮助.

public static Method method[];
public static MethodClass obj;
public static String testMethod="A";

public static void main(String args[]) 
{
    obj=new MethodClass();
    method=obj.getClass().getMethods();
    try
    {
        for(int i=0;i

谢谢....



12> Marcel..:

我这样做是这样的:

try {
    YourClass yourClass = new YourClass();
    Method method = YourClass.class.getMethod("yourMethodName", ParameterOfThisMethod.class);
    method.invoke(yourClass, parameter);
} catch (Exception e) {
    e.printStackTrace();
}



13> 小智..:
Method method = someVariable.class.getMethod(SomeClass);
String status = (String) method.invoke(method);

SomeClass是类,someVariable是变量。

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有