Làm thế nào để tôi gọi một phương thức Java khi được đặt tên phương thức là một chuỗi?


684

Nếu tôi có hai biến:

Object obj;
String methodName = "getName";

Không biết lớp của obj, làm thế nào tôi có thể gọi phương thức được xác định bởi methodNamenó?

Phương thức được gọi không có tham số và Stringgiá trị trả về. Đó là một getter cho một Java bean .


3
Hoặc sử dụng api phản chiếu hoặc sử dụng Groovy
Peter Kelley

Câu trả lời:


972

Mã hóa từ hông, nó sẽ là một cái gì đó như:

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

Các tham số xác định phương thức rất cụ thể mà bạn cần (nếu có sẵn một số quá tải, nếu phương thức không có đối số, chỉ đưa ra methodName).

Sau đó, bạn gọi phương thức đó bằng cách gọi

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

Một lần nữa, bỏ qua các đối số trong .invoke, nếu bạn không có bất kỳ. Nhưng vâng. Đọc về Phản xạ Java


2
Đã có một chút khó chịu khi thực tế là Java sử dụng kiểu xóa, nhưng biết rằng ít nhất nó cũng có Reflection làm tôi phấn khích trở lại: D Và bây giờ với lambdas trong Java 8, ngôn ngữ đang thực sự bắt kịp tốc độ phát triển hiện đại. Điều duy nhất còn thiếu bây giờ là hỗ trợ riêng cho getters và setters hoặc các thuộc tính như chúng được biết đến trong C #.
7hi4g0

120
Không công bằng -1. Henrik có lẽ không ủng hộ các trường hợp ngoại lệ và không viết bất cứ điều gì cho họ vì anh ta chỉ cố gắng thể hiện sự phản ánh.
đã vẽ

70
Thêm một cho thấy một số ngoại lệ tiềm năng. Nếu tôi đã viết cái này, nó sẽ là ... bắt (Ngoại lệ e) {...
mikbanUtah

1
Tôi đã nhận "biến có thể chưa được khởi tạo" cho methodin method.invoke(obj, arg1, arg2,...);. một method = null;giải quyết vấn đề nhưng đề cập đến nó trong câu trả lời không phải là một ý tưởng tồi.
Amin

2
Các phương thức Java @ DeaMon1 không sử dụng "mã thoát", nhưng nếu phương thức trả về bất cứ thứ gì, invokesẽ trả về bất cứ thứ gì nó trả về. Nếu một ngoại lệ xảy ra khi chạy phương thức, ngoại lệ sẽ được bọc trong một InvocationTargetException.
ThePyroEagle

194

Sử dụng lời gọi phương thức từ sự phản chiếu:

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

Ở đâu:

  • "class name" là tên của lớp
  • objectToInvokeOn thuộc loại Object và là đối tượng bạn muốn gọi phương thức trên
  • "method name" là tên của phương thức bạn muốn gọi
  • parameterTypeslà kiểu Class[]và khai báo các tham số mà phương thức lấy
  • paramslà kiểu Object[]và khai báo các tham số được truyền cho phương thức

Thật tuyệt, tôi nghĩ rằng bạn đúng với getDeclaredMethod (), nó có thể 'an toàn' hơn getMethod () ..
Brasskazoo

22
Sai lầm. Có, getDeclaredMethod hoạt động với các phương thức riêng tư và được bảo vệ. NHƯNG: nó không hoạt động với các phương thức được định nghĩa trong siêu lớp (phương thức kế thừa). Vì vậy, nó phụ thuộc mạnh mẽ vào những gì bạn muốn làm. Trong nhiều trường hợp, bạn muốn nó hoạt động bất kể lớp chính xác mà phương thức được định nghĩa.
jrudolph

Và tôi nên đặt tập tin "lớp" ở đâu? tốt nhất là giải thích cho IDE Eclipse
Dr.jacky

@ Mr.Hyde trên con đường lớp.
Stijn de Witt

Tôi nên đặt gì bên trong và method.invoke () nếu phương thức tôi đang gọi không chấp nhận bất kỳ tham số nào cả? Có vẻ như tôi vẫn phải cung cấp tham số thứ hai, nó có nên là một mảng Object trống không?
Igor

101

Đối với những người muốn có một ví dụ mã thẳng trong Java 7:

Dog lớp học:

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 lớp học:

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

Đầu ra: Mishka is 3 year(s) old.


Bạn có thể gọi hàm tạo với các tham số theo cách này:

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

Ngoài ra, bạn có thể loại bỏ

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

và làm

Dog dog = new Dog();

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

Đề nghị đọc: Tạo trường hợp lớp mới


1
Câu trả lời tốt nhất ở đây. Hoàn thành và súc tích
Reuben JaMes Aveño Gruta

1
Câu trả lời đúng nhất.
Dhara Patel

Nơi nào bạn nhận được Methodđối tượng?
parlad

Từ pkg phản ánh.
bạc

55

Phương thức có thể được gọi như thế này. Ngoài ra còn có nhiều khả năng hơn (kiểm tra api phản chiếu), nhưng đây là cách đơn giản nhất:

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



}

7
+1 cho câu trả lời duy nhất nhận ra rằng OP đã chỉ định "không có tham số" trong câu hỏi của anh ấy (và vì đó cũng là điều tôi đang tìm kiếm).
John Fitzpatrick

16

Đầu tiên, đừng. Tránh loại mã này. Nó có xu hướng là mã thực sự xấu và cũng không an toàn (xem phần 6 của Nguyên tắc mã hóa bảo mật cho ngôn ngữ lập trình Java, phiên bản 2.0 ).

Nếu bạn phải làm điều đó, thích java.beans để phản ánh. Đậu kết thúc phản xạ cho phép truy cập tương đối an toàn và thông thường.


11
Tôi không đồng ý. Rất dễ dàng để viết mã như vậy để được an toàn và tôi đã làm như vậy bằng nhiều ngôn ngữ. Ví dụ, người ta có thể tạo một tập hợp các phương thức được phép và chỉ cho phép một phương thức được gọi nếu tên của nó nằm trong tập hợp. Thậm chí an toàn hơn (nhưng vẫn đơn giản là xương đầu) sẽ giới hạn mỗi phương thức được phép ở một trạng thái cụ thể và không cho phép phương thức được gọi trừ khi chủ đề / giao diện / người dùng / bất cứ điều gì phù hợp với tiêu chí đó.
JSON

Không bao giờ được phân loại như vậy về các vấn đề như vậy. Ngay bây giờ tôi đang tạo một chương trình đơn giản để cho phép người dùng xác định các tác vụ tùy ý trên các đối tượng tùy ý bằng giao diện web. Tôi biết rằng, thực sự là không an toàn, nhưng việc kiểm tra thích hợp được thực hiện sau khi nhận được cấu hình và nó cho phép người không lập trình dễ dàng cấu hình các tác vụ và cũng cung cấp cho các chương trình khả năng liên kết các lớp tùy chỉnh với mã chung (đó là phần tôi sử dụng sự phản chiếu để, cho phép họ định cấu hình phương thức nào sẽ sử dụng qua giao diện web) mà không phải cập nhật GUI.
DGoiko

14

Để hoàn thành câu trả lời của đồng nghiệp của tôi, Bạn có thể muốn chú ý đến:

  • các cuộc gọi tĩnh hoặc cá thể (trong một trường hợp, bạn không cần một thể hiện của lớp, trong trường hợp khác, bạn có thể cần phải dựa vào một hàm tạo mặc định hiện có có thể có hoặc không có ở đó)
  • Cuộc gọi phương thức công khai hoặc không công khai (đối với cuộc gọi sau, bạn cần gọi setAccessible trên phương thức trong một khối doPriv đặc quyền , các công cụ tìm kiếm khác sẽ không vui )
  • gói gọn vào một ngoại lệ áp dụng dễ quản lý hơn nếu bạn muốn loại bỏ nhiều ngoại lệ của hệ thống java (do đó, CCException trong mã bên dưới)

Đây là một mã java1.4 cũ có tính đến các điểm đó:

/**
 * Allow for instance call, avoiding certain class circular dependencies. <br />
 * 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;
}

12
Object obj;

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

method.invoke(obj, null);

Đối tượng nên có ít nhất giá trị / giá trị.
Lova Chittumuri

Điều này làm việc thực sự tốt cho những gì tôi cần. Tôi đã có một lớp đã được khởi tạo và chỉ cần có một phương thức từ nó. Thêm các sản phẩm khai thác cho các trường hợp ngoại lệ là một ý tưởng tốt ở đây, nhưng nếu không, điều này làm việc hoàn hảo với tôi. Tôi nghĩ rằng cách của tôi để tránh các ngoại lệ null là sử dụng nullables, nhưng tôi đã sử dụng một phạm vi tên phương thức rất hạn chế (nghĩa đen chỉ là một bộ đếm từ 1 đến 4).
Jain Waldrip

12
//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");

8

Nếu bạn thực hiện cuộc gọi nhiều lần, bạn có thể sử dụng các điều khiển phương thức mới được giới thiệu trong Java 7. Ở đây chúng tôi sẽ cho phương thức của bạn trả về một Chuỗi:

Object obj = new Point( 100, 200 );
String methodName = "toString";  
Class<String> 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]

1
Để độc giả tương lai; Nếu bạn quan tâm đến hiệu suất, bạn sẽ muốn sử dụng invokeExactbất cứ khi nào bạn có thể. Do đó, chữ ký trang web cuộc gọi phải khớp chính xác với loại xử lý phương thức. Nó thường mất một chút mày mò để đi làm. Trong trường hợp này, bạn cần truyền tham số đầu tiên bằng: methodHandle = methodHandle.asType(methodHandle.type().changeParameterType(0, Object.class));và sau đó gọi nhưString result = (String) methodHandle.invokeExact(obj);
Jorn Vernee

7

Điều này nghe có vẻ như có thể thực hiện được với gói Java Reflection.

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

Đặc biệt theo Phương thức gọi theo tên:

nhập 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);
     }
  }
}

6

Lập chỉ mục (nhanh hơn)

Bạn có thể sử dụng FunctionalInterfaceđể lưu các phương thức trong một thùng chứa để lập chỉ mục cho chúng. Bạn có thể sử dụng bộ chứa mảng để gọi chúng bằng số hoặc hàm băm để gọi chúng theo chuỗi. Bằng thủ thuật này, bạn có thể lập chỉ mục các phương thức của mình để gọi chúng một cách linh hoạt nhanh hơn .

@FunctionalInterface
public interface Method {
    double execute(int number);
}

public class ShapeArea {
    private final static double PI = 3.14;

    private Method[] methods = {
        this::square,
        this::circle
    };

    private double square(int number) {
        return number * number;
    }

    private double circle(int number) {
        return PI * number * number;
    }

    public double run(int methodIndex, int number) {
        return methods[methodIndex].execute(aNumber);
    }
}

Cú pháp Lambda

Bạn cũng có thể sử dụng cú pháp lambda:

public class ShapeArea {
    private final static double PI = 3.14;

    private Method[] methods = {
        number -> {
            return number * number;
        },
        number -> {
            return PI * number * number;
        },
    };

    public double run(int methodIndex, int number) {
        return methods[methodIndex].execute(aNumber);
    }
}

1
Kỹ thuật này có vẻ tốt hơn nhiều so với phản xạ.
John O

Nó thực sự tốt hơn nhiều?
Dimitri Kopriwa

@DimitriKopriwa Lập chỉ mục là cách bạn sử dụng ram thay vì tính toán CPU. Đối với lập chỉ mục số nguyên, độ khó của thuật toán là O(1).
Amir cho

5
Method method = someVariable.class.getMethod(SomeClass);
String status = (String) method.invoke(method);

SomeClasslà lớp và someVariablelà một biến.


nếu someVariable thực sự là một đối tượng, hãy gọi someVariable.getClass (). Ngoài ra, bạn không thể gọi getMethod () với một lớp làm đối số duy nhất. Không gọi phương thức với phương thức. Đúng: someVariable.getClass (). GetMethod ("coolMethod", tham sốClass) .invoke (đối số);
Orangle

5

Tôi làm như thế này:

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

5

Vui lòng tham khảo mã sau đây có thể giúp bạn.

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<method.length;i++)
        {
            String name=method[i].getName();
            if(name==testMethod)
            {   
                method[i].invoke(name,"Test Parameters of A");
            }
        }
    }
    catch(Exception ex)
    {
        System.out.println(ex.getMessage());
    }
}

Cảm ơn....


Đây không phải là cách bạn so sánh Chuỗi trong Java. Bạn phải sử dụng phương pháp .equals. Mặt khác, bạn chỉ đang so sánh rằng chúng là cùng một tham chiếu đối tượng và bạn không thực sự quan tâm đến các tham chiếu đối tượng - chỉ nội dung chuỗi là khớp. Bạn cũng có thể nhận được phương thức theo tên thông qua sự phản chiếu, vì vậy không chắc chắn tại sao bạn sẽ tự lăn?
Lo-Tân

5

Dưới đây là S READN SÀNG SỬ DỤNG PHƯƠNG PHÁP:

Để gọi một phương thức, không có đối số:

public static void callMethodByName(Object object, String methodName) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    object.getClass().getDeclaredMethod(methodName).invoke(object);
}

Để gọi một phương thức, với các đối số:

    public static void callMethodByName(Object object, String methodName, int i, String s) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        object.getClass().getDeclaredMethod(methodName, int.class, String.class).invoke(object, i, s);
    }

Sử dụng các phương pháp trên như dưới đây:

package practice;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

public class MethodInvoke {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
        String methodName1 = "methodA";
        String methodName2 = "methodB";
        MethodInvoke object = new MethodInvoke();
        callMethodByName(object, methodName1);
        callMethodByName(object, methodName2, 1, "Test");
    }

    public static void callMethodByName(Object object, String methodName) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        object.getClass().getDeclaredMethod(methodName).invoke(object);
    }

    public static void callMethodByName(Object object, String methodName, int i, String s) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        object.getClass().getDeclaredMethod(methodName, int.class, String.class).invoke(object, i, s);
    }

    void methodA() {
        System.out.println("Method A");
    }

    void methodB(int i, String s) {
        System.out.println("Method B: "+"\n\tParam1 - "+i+"\n\tParam 2 - "+s);
    }
}

Đầu ra:

Phương pháp A  
Phương pháp B:  
	Tham số 1 - 1  
	Tham số 2 - Kiểm tra

3

Student.java

class Student{
    int rollno;
    String name;

    void m1(int x,int y){
        System.out.println("add is" +(x+y));
    }

    private void m3(String name){
        this.name=name;
        System.out.println("danger yappa:"+name);
    }
    void m4(){
        System.out.println("This is m4");
    }
}

StudentTest.java

import java.lang.reflect.Method;
public class StudentTest{

     public static void main(String[] args){

        try{

            Class cls=Student.class;

            Student s=(Student)cls.newInstance();


            String x="kichha";
            Method mm3=cls.getDeclaredMethod("m3",String.class);
            mm3.setAccessible(true);
            mm3.invoke(s,x);

            Method mm1=cls.getDeclaredMethod("m1",int.class,int.class);
            mm1.invoke(s,10,20);

        }
        catch(Exception e){
            e.printStackTrace();
        }
     }
}

1

Bạn nên sử dụng sự phản chiếu - khởi tạo một đối tượng lớp, sau đó là một phương thức trong lớp này và sau đó gọi phương thức này trên một đối tượng với các tham số tùy chọn . Nhớ bọc đoạn mã sau trong khối thử

Hy vọng nó giúp!

Class<?> aClass = Class.forName(FULLY_QUALIFIED_CLASS_NAME);
Method method = aClass.getMethod(methodName, YOUR_PARAM_1.class, YOUR_PARAM_2.class);
method.invoke(OBJECT_TO_RUN_METHOD_ON, YOUR_PARAM_1, YOUR_PARAM_2);

1

Điều này đang làm việc tốt cho tôi:

public class MethodInvokerClass {
    public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, ClassNotFoundException, InvocationTargetException, InstantiationException {
        Class c = Class.forName(MethodInvokerClass.class.getName());
        Object o = c.newInstance();
        Class[] paramTypes = new Class[1];
        paramTypes[0]=String.class;
        String methodName = "countWord";
         Method m = c.getDeclaredMethod(methodName, paramTypes);
         m.invoke(o, "testparam");
}
public void countWord(String input){
    System.out.println("My input "+input);
}

}

Đầu ra:

My input testparam

Tôi có thể gọi phương thức bằng cách chuyển tên của nó sang phương thức khác (như chính).


1

sử dụng import java.lang.reflect.*;

public static Object launchProcess(String className, String methodName, Class<?>[] argsTypes, Object[] methodArgs)
        throws Exception {

    Class<?> processClass = Class.forName(className); // convert string classname to class
    Object process = processClass.newInstance(); // invoke empty constructor

    Method aMethod = process.getClass().getMethod(methodName,argsTypes);
    Object res = aMethod.invoke(process, methodArgs); // pass arg
    return(res);
}

và đây là cách bạn sử dụng nó:

String className = "com.example.helloworld";
String methodName = "print";
Class<?>[] argsTypes = {String.class,  String.class};
Object[] methArgs = { "hello", "world" };   
launchProcess(className, methodName, argsTypes, methArgs);

0

Với jooR, nó chỉ đơn thuần là:

on(obj).call(methodName /*params*/).get()

Dưới đây là một ví dụ chi tiết hơn:

public class TestClass {

    public int add(int a, int b) { return a + b; }
    private int mul(int a, int b) { return a * b; }
    static int sub(int a, int b) { return a - b; }

}

import static org.joor.Reflect.*;

public class JoorTest {

    public static void main(String[] args) {
        int add = on(new TestClass()).call("add", 1, 2).get(); // public
        int mul = on(new TestClass()).call("mul", 3, 4).get(); // private
        int sub = on(TestClass.class).call("sub", 6, 5).get(); // static
        System.out.println(add + ", " + mul + ", " + sub);
    }
}

Bản in này:

3, 12, 1


-10

đối với tôi một cách chứng minh khá đơn giản và ngu ngốc sẽ chỉ đơn giản là tạo một phương thức gọi phương thức như vậy:

public static object methodCaller(String methodName)
{
    if(methodName.equals("getName"))
        return className.getName();
}

sau đó khi bạn cần gọi phương thức đơn giản chỉ cần đặt một cái gì đó như thế này

//calling a toString method is unnessary here, but i use it to have my programs to both rigid and self-explanitory 
System.out.println(methodCaller(methodName).toString()); 

4
Nếu ví dụ đã được biết đến trong thời gian làm việc, tại sao bạn không làm className.getName().toString()? Bạn đang thiếu toàn bộ điểm phản ánh.
BalusC

Như tôi đã nói, không cần thiết trong trường hợp này, nhưng giả sử bạn sẽ luôn biết ví dụ là một thói quen lập trình xấu.
SMayne

2
@SMayne: Tôi sẽ đề nghị xóa bài đăng này.
lpapp

lập trình xấu sẽ là một lời khen trong trường hợp này
pdenti
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.