Bagaimana cara menjalankan metode Java saat diberi nama metode sebagai string?

684

Jika saya memiliki dua variabel:

Object obj;
String methodName = "getName";

Tanpa mengetahui kelasnya obj, bagaimana saya bisa memanggil metode yang diidentifikasi methodNameolehnya?

Metode yang dipanggil tidak memiliki parameter, dan Stringnilai balik. Ini pengambil untuk kacang Jawa .

brasskazoo
sumber
3
Baik gunakan api pantulan atau gunakan asyik
Peter Kelley

Jawaban:

972

Mengodekan dari pinggul, itu akan menjadi seperti:

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

Parameter mengidentifikasi metode yang sangat spesifik yang Anda butuhkan (jika ada beberapa kelebihan beban tersedia, jika metode tidak memiliki argumen, hanya berikan methodName).

Kemudian Anda memanggil metode itu dengan menelepon

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

Sekali lagi, tinggalkan argumen .invoke, jika Anda tidak punya. Tapi ya. Baca tentang Java Reflection

Henrik Paul
sumber
2
Sedikit kesal dengan kenyataan bahwa Jawa menggunakan tipe erasure, tetapi mengetahui bahwa setidaknya ia memiliki Reflection membuatku senang lagi: D Dan sekarang dengan lambdas di Jawa 8 bahasa ini benar-benar semakin cepat dengan perkembangan modern. Satu-satunya hal yang hilang sekarang adalah dukungan asli untuk getter dan setter, atau properti seperti yang dikenal dalam C #.
7hi4g0
120
Tidak adil -1. Henrik mungkin tidak menganjurkan pengecualian squashing dan tidak menulis apa pun untuk mereka karena dia hanya mencoba untuk menunjukkan refleksi.
menggambar
70
Plus satu untuk menunjukkan beberapa pengecualian potensial. Jika saya menulis ini, itu akan menjadi ... catch (Exception e) {...
mikbanUtah
1
Saya mendapat "variabel mungkin belum diinisialisasi" untuk methoddi method.invoke(obj, arg1, arg2,...);. a method = null;memecahkan masalah tetapi menyebutkannya dalam jawaban bukanlah ide yang buruk.
Amin
2
@ DeaMon1 metode Java tidak menggunakan "kode keluar", tetapi jika metode mengembalikan apa pun, invokeakan mengembalikan apa pun yang dikembalikan. Jika pengecualian terjadi menjalankan metode, pengecualian akan dibungkus dengan InvocationTargetException.
ThePyroEagle
194

Gunakan doa metode dari refleksi:

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

Dimana:

  • "class name" adalah nama kelas
  • objectToInvokeOn bertipe Object dan merupakan objek yang ingin Anda panggil metode ini
  • "method name" adalah nama metode yang ingin Anda panggil
  • parameterTypesadalah tipe Class[]dan menyatakan parameter yang digunakan metode
  • paramsadalah tipe Object[]dan mendeklarasikan parameter untuk diteruskan ke metode
Owen
sumber
Keren, saya pikir Anda benar dengan getDeclaredMethod (), mungkin 'lebih aman' daripada getMethod () ..
brasskazoo
22
Salah. Ya, getDeclaredMethod berfungsi dengan metode pribadi dan terlindungi. TETAPI: itu tidak bekerja dengan metode yang didefinisikan dalam superclasses (metode warisan). Jadi, ini sangat tergantung pada apa yang ingin Anda lakukan. Dalam banyak kasus Anda ingin itu berfungsi terlepas dari kelas yang tepat di mana metode ini didefinisikan.
jrudolph
Dan di mana saya harus meletakkan file "class"? sebaiknya jelaskan untuk Eclipse IDE
Dr.jacky
@ Mr.Hyde di jalur kelas.
Stijn de Witt
Apa yang harus saya masukkan ke dalam dan method.invoke () jika metode yang saya panggil tidak menerima parameter sama sekali? Tampaknya saya masih harus memberikan parameter kedua, haruskah itu menjadi array Obyek kosong?
Igor
101

Bagi mereka yang menginginkan contoh kode langsung di Java 7:

Dog kelas:

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

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

Keluaran: Mishka is 3 year(s) old.


Anda dapat memanggil konstruktor dengan parameter dengan cara ini:

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

Atau, Anda dapat menghapus

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

dan lakukan

Dog dog = new Dog();

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

Bacaan yang disarankan: Membuat Instance Kelas Baru

perak
sumber
1
Jawaban terbaik di sini. Lengkap dan ringkas
Reuben JaMes Aveño Gruta
1
Benar Jawaban terbaik.
Dhara Patel
Di mana Anda mendapatkan Methodobjek?
parlad
Dari pkg mencerminkan.
perak
55

Metode ini dapat dipanggil seperti ini. Ada juga lebih banyak kemungkinan (periksa api refleksi), tetapi ini adalah yang paling sederhana:

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



}
Petr Macek
sumber
7
+1 untuk satu-satunya jawaban yang mengakui bahwa OP menentukan "tidak ada parameter" dalam pertanyaannya (dan karena itulah yang saya cari juga).
John Fitzpatrick
16

Pertama, jangan. Hindari kode semacam ini. Kode ini cenderung sangat buruk dan tidak aman juga (lihat bagian 6 dari Panduan Pengkodean Aman untuk Bahasa Pemrograman Java, versi 2.0 ).

Jika Anda harus melakukannya, lebih suka java.beans daripada refleksi. Kacang membungkus refleksi memungkinkan akses yang relatif aman dan konvensional.

Tom Hawtin - tackline
sumber
11
Saya tidak setuju. Sangat mudah untuk menulis kode semacam itu agar aman dan saya telah melakukannya dalam berbagai bahasa. Sebagai contoh, seseorang dapat membuat satu set metode yang diijinkan, dan hanya memungkinkan metode untuk dipanggil jika namanya ada di set. Bahkan yang lebih aman (namun tetap sederhana) akan membatasi setiap metode yang diizinkan untuk keadaan tertentu, dan tidak mengizinkan metode untuk dipanggil kecuali utas / antarmuka / pengguna / apa pun yang sesuai dengan kriteria tersebut.
JSON
Jangan pernah terlalu kategoris tentang masalah seperti itu. Saat ini saya sedang membuat program sederhana untuk memungkinkan pengguna untuk mendefinisikan tugas-tugas sewenang-wenang atas objek yang sewenang-wenang menggunakan antarmuka web. Saya tahu ini memang tidak aman, tetapi pengujian yang tepat dilakukan setelah konfigurasi diterima, dan memungkinkan non-programmer untuk dengan mudah mengkonfigurasi tugas, dan juga memberikan program kemampuan untuk menghubungkan kelas khusus ke kode generik (itulah yang bagian saya menggunakan refleksi untuk, agar mereka dapat mengkonfigurasi metode mana yang digunakan melalui antarmuka web) tanpa harus memperbarui GUI.
DGoiko
14

Untuk melengkapi jawaban kolega saya, Anda mungkin ingin memperhatikan:

  • panggilan statis atau instance (dalam satu kasus, Anda tidak perlu turunan kelas, di lain, Anda mungkin harus bergantung pada konstruktor default yang ada yang mungkin ada atau tidak ada di sana)
  • panggilan metode publik atau non-publik (untuk yang terakhir, Anda perlu memanggil setAccessible pada metode dalam blok doPrivileged , findbugs lain tidak akan senang )
  • merangkum menjadi satu pengecualian aplikatif yang lebih mudah dikelola jika Anda ingin membuang kembali banyak pengecualian sistem java (karenanya CCException dalam kode di bawah)

Berikut ini adalah kode java1.4 lama yang memperhitungkan poin-poin tersebut:

/**
 * 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;
}
VONC
sumber
12
Object obj;

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

method.invoke(obj, null);
chickeninabiscuit
sumber
Objek setidaknya harus memiliki nilai / nilai.
Lova Chittumuri
Ini bekerja sangat baik untuk apa yang saya butuhkan. Saya memiliki kelas yang sudah dipakai dan hanya perlu untuk mendapatkan metode dari itu. Menambahkan tangkapan untuk pengecualian adalah ide yang bagus di sini, tetapi sebaliknya, ini bekerja dengan baik untuk saya. Saya pikir cara saya menghindari pengecualian nol adalah dengan menggunakan nullables, tetapi saya menggunakan rentang nama metode yang sangat terbatas (secara harfiah hanya sebuah penghitung dari 1 hingga 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");
anujin
sumber
8

Jika Anda melakukan panggilan beberapa kali, Anda dapat menggunakan metode baru menangani diperkenalkan di Java 7. Di sini kita pergi untuk metode Anda mengembalikan sebuah String:

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]
Christian Ullenboom
sumber
1
Untuk pembaca masa depan; Jika Anda peduli tentang kinerja, Anda akan ingin menggunakannya invokeExactkapan pun Anda bisa. Untuk itu, tanda tangan situs panggilan harus sama persis dengan tipe pegangan metode. Biasanya perlu sedikit waktu untuk mulai bekerja. Dalam hal ini Anda harus memberikan parameter pertama dengan: methodHandle = methodHandle.asType(methodHandle.type().changeParameterType(0, Object.class));dan kemudian memanggil sepertiString result = (String) methodHandle.invokeExact(obj);
Jorn Vernee
7

Ini terdengar seperti sesuatu yang bisa dilakukan dengan paket Java Reflection.

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

Khususnya di bawah Metode Meminta berdasarkan Nama:

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);
     }
  }
}
zxcv
sumber
6

Pengindeksan (lebih cepat)

Anda dapat menggunakan FunctionalInterfaceuntuk menyimpan metode dalam wadah untuk mengindeksnya. Anda bisa menggunakan wadah array untuk memanggil mereka dengan angka atau hashmap untuk memanggil mereka dengan string. Dengan trik ini, Anda dapat mengindeks metode Anda untuk memanggil mereka secara dinamis lebih cepat .

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

Sintaks Lambda

Anda juga dapat menggunakan sintaks 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);
    }
}
Amir Fo
sumber
1
Teknik ini tampaknya jauh lebih baik daripada refleksi.
John O
Apakah ini jauh lebih baik?
Dimitri Kopriwa
@DimitriKopriwa Pengindeksan adalah cara Anda menggunakan ram alih-alih perhitungan CPU. Untuk pengindeksan bilangan bulat, kesulitan algoritma adalah O(1).
Amir Fo
5
Method method = someVariable.class.getMethod(SomeClass);
String status = (String) method.invoke(method);

SomeClassadalah kelas dan someVariablemerupakan variabel.

Subrahmanya Prasad
sumber
jika someVariable benar-benar objek, panggil someVariable.getClass (). Selain itu, Anda tidak dapat memanggil getMethod () dengan kelas sebagai satu-satunya argumen. Tidak menggunakan metode dengan metode. Benar: someVariable.getClass (). GetMethod ("coolMethod", parameterClasses) .invoke (argumen);
Orangle
5

Saya melakukan ini seperti ini:

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

Silakan merujuk kode berikut ini dapat membantu Anda.

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

Terima kasih....

Rahul Karankal
sumber
Ini bukan bagaimana Anda membandingkan String di Jawa. Anda harus menggunakan metode .equals. Kalau tidak, Anda hanya membandingkan bahwa mereka adalah referensi objek yang sama, dan Anda tidak benar-benar peduli tentang referensi objek - hanya konten string yang cocok. Anda juga bisa mendapatkan metode dengan nama melalui refleksi, jadi tidak yakin mengapa Anda akan menggunakan metode Anda sendiri?
Lo-Tan
5

Berikut adalah METODE SIAP MENGGUNAKAN:

Untuk memanggil metode, tanpa Argumen:

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

Untuk memanggil metode, dengan Argumen:

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

Gunakan metode di atas seperti di bawah ini:

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

Keluaran:

Metode A  
Metode B:  
	Param1 - 1  
	Param 2 - Tes
Sandeep Nalla
sumber
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();
        }
     }
}
pengguna8387971
sumber
1

Anda harus menggunakan refleksi - init objek kelas, lalu metode di kelas ini, dan kemudian memanggil metode ini pada objek dengan parameter opsional . Ingatlah untuk membungkus potongan berikut dalam blok coba-tangkap

Semoga ini bisa membantu!

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);
detman
sumber
1

Ini berfungsi dengan baik untuk saya:

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

}

Keluaran:

My input testparam

Saya dapat memanggil metode dengan memberikan namanya ke metode lain (seperti main).

Laxman G
sumber
1

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

dan inilah cara Anda menggunakannya:

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

Dengan jooR itu hanyalah:

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

Berikut ini adalah contoh yang lebih rumit:

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

Ini mencetak:

3, 12, 1

Andronicus
sumber
-10

bagi saya cara pembuktian yang cukup sederhana dan bodoh adalah dengan membuat metode metode pemanggil seperti:

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

maka ketika Anda perlu memanggil metode cukup taruh sesuatu seperti ini

//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()); 
SMayne
sumber
4
Jika instance sudah dikenal selama compiletime, kenapa tidak Anda lakukan saja className.getName().toString()? Anda melewatkan seluruh titik refleksi.
BalusC
Seperti yang saya katakan, tidak perlu dalam kasus ini, tetapi dengan asumsi Anda akan selalu tahu contoh adalah kebiasaan pemrograman yang buruk.
SMayne
2
@ Mayne: Saya akan menyarankan untuk menghapus posting ini.
lpapp
pemrograman yang buruk lebih suka menjadi pujian dalam kasus ini
pdenti