स्ट्रिंग के रूप में विधि नाम दिए जाने पर मैं जावा विधि कैसे लागू करूं?


684

अगर मेरे पास दो चर हैं:

Object obj;
String methodName = "getName";

की कक्षा को जाने बिना obj, मैं उस methodNameपर पहचाने गए तरीके को कैसे कह सकता हूं ?

कहा जा रहा विधि में कोई पैरामीटर नहीं है, और एक Stringवापसी मूल्य है। यह जावा बीन के लिए एक गेट्टर है


जवाबों:


972

कूल्हे से कोडिंग, यह कुछ इस तरह होगा:

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यदि आपके पास कोई नहीं है, तो फिर से, तर्कों को छोड़ दें । लेकिन हाँ। जावा प्रतिबिंब के बारे में पढ़ें


2
इस तथ्य से थोड़ा परेशान था कि जावा टाइप इरेज़र का उपयोग करता है, लेकिन यह जानते हुए कि कम से कम इसमें परावर्तन मुझे फिर से खुश करता है: डी और अब जावा 8 में लैम्ब्डा के साथ भाषा वास्तव में आधुनिक विकास के साथ गति करने के लिए उठ रही है। केवल एक चीज अब गायब है जो गेटर्स और सेटर्स के लिए मूल समर्थन है, या गुणों के रूप में वे सी # में ज्ञात हैं।
7hi4g0

120
मेला नहीं -1। हेनरिक संभवतः अपवादों को स्वीकार करने की वकालत नहीं कर रहे हैं और उन्होंने उनके लिए कुछ भी नहीं लिखा क्योंकि वह केवल प्रतिबिंब प्रदर्शित करने की कोशिश कर रहे हैं।
आकर्षित किया

70
प्लस कुछ संभावित अपवाद दिखाने के लिए। अगर मैंने यह लिखा होता, तो यह होता ... कैच (अपवाद e) {...
mikbanUtah

1
मुझे मिल गया के लिए "चर प्रारंभ नहीं किया गया है" methodमें method.invoke(obj, arg1, arg2,...);। एक method = null;हल समस्या लेकिन जवाब में उसका उल्लेख कर एक बुरा विचार नहीं है।
अमीन

2
@ DeaMon1 Java मेथड्स "एक्जिट कोड्स" का उपयोग नहीं करते हैं, लेकिन यदि विधि कुछ भी लौटाती है, invokeतो जो भी लौटा है उसे वापस कर देगी। यदि कोई अपवाद विधि को चलाता है, तो अपवाद को एक में लपेटा जाएगा InvocationTargetException
thePyroEagle

194

प्रतिबिंब से विधि आह्वान का उपयोग करें :

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

कहाँ पे:

  • "class name" वर्ग का नाम है
  • objectToInvokeOn प्रकार की वस्तु है और वह वस्तु है जिस पर आप विधि लागू करना चाहते हैं
  • "method name" उस विधि का नाम है जिसे आप कॉल करना चाहते हैं
  • parameterTypesप्रकार का है Class[]और उन तरीकों की घोषणा करता है जो विधि लेता है
  • paramsप्रकार है Object[]और विधि को पारित करने की घोषणा करता है

कूल, मुझे लगता है कि आप getDeclaredMethod () के साथ सही हैं, यह शायद getMethod () की तुलना में 'अधिक सुरक्षित' है
पीतलकाज़ू

22
गलत। हां, getDeclaredMethod निजी और संरक्षित विधियों के साथ काम करता है। लेकिन: यह सुपरक्लासेस (विरासत में मिली विधियों) में परिभाषित तरीकों से काम नहीं करता है। तो, यह दृढ़ता से निर्भर करता है कि आप क्या करना चाहते हैं। कई मामलों में आप चाहते हैं कि यह उस सटीक वर्ग की परवाह किए बिना काम करे जिसमें यह पद्धति परिभाषित है।
--8

और मुझे "क्लास" फ़ाइल कहाँ रखनी चाहिए? ग्रहण आईडीई के लिए अधिमानतः समझाएं
डॉजकी

@ श्री राहे वर्ग पथ पर।
स्टिजन डे विट

मुझे और मेथड के अंदर क्या रखना चाहिए। ऐसा लगता है कि मुझे अभी भी दूसरा पैरामीटर प्रदान करना है, क्या यह कुछ खाली ऑब्जेक्ट सरणी होना चाहिए?
इगोर

101

उन लोगों के लिए जो जावा 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, ...);

सुझाव पढ़ना: नई कक्षा के उदाहरण बनाना


1
यहाँ सबसे अच्छा जवाब। पूरा और संक्षिप्त
रूबेन जेएमस एवोनो ग्रूटा

1
सही उत्तर।
धरा पटेल

Methodवस्तु कहाँ से मिलती है?
7

रिफ्लेक्ट pkg से।
रजत

55

विधि को इस तरह लागू किया जा सकता है। अधिक संभावनाएं भी हैं (प्रतिबिंब एपीआई की जांच करें), लेकिन यह सबसे सरल है:

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 ने केवल एक ही उत्तर के लिए मान्यता दी कि ओपी ने अपने प्रश्न में "कोई पैरामीटर नहीं" निर्दिष्ट किया (और क्योंकि यह वही था जो मैं भी खोज रहा था)।
जॉन फिट्जपैट्रिक

16

सबसे पहले, नहीं। इस तरह के कोड से बचें। यह वास्तव में बुरा कोड है और असुरक्षित भी है ( जावा प्रोग्रामिंग भाषा, संस्करण 2.0 के लिए सुरक्षित कोडिंग दिशानिर्देशों की धारा 6 देखें )।

यदि आप इसे करते हैं, तो प्रतिबिंब के लिए java.beans को प्राथमिकता दें। बीन्स अपेक्षाकृत सुरक्षित और पारंपरिक पहुंच की अनुमति देता है।


11
मैं असहमत हूं। इस तरह के कोड को सुरक्षित रखना बहुत आसान है और मैंने कई भाषाओं में ऐसा किया है। उदाहरण के लिए, एक स्वीकार्य तरीकों का एक सेट बना सकता है, और केवल एक विधि को लागू करने की अनुमति देता है यदि यह सेट में है। इससे भी अधिक सुरक्षित (अभी तक हड्डी-सिर सरल) प्रत्येक अनुमत विधि को एक विशिष्ट स्थिति तक सीमित कर देगा, और जब तक कि थ्रेड / इंटरफ़ेस / उपयोगकर्ता / जो भी इस तरह के मानदंडों को फिट नहीं करता है, तो विधि को लागू करने की अनुमति नहीं दी जाएगी।
JSON

इस तरह के मुद्दों के बारे में कभी भी स्पष्ट न हों। अभी मैं एक साधारण प्रोग्राम बना रहा हूँ जिससे उपयोगकर्ता वेब इंटरफेस का उपयोग करके मनमानी वस्तुओं पर मनमाने कार्यों को परिभाषित कर सके। मुझे पता है कि यह वास्तव में असुरक्षित है, लेकिन एक बार कॉन्फ़िगरेशन प्राप्त होने के बाद उचित परीक्षण किया जाता है, और यह गैर-प्रोग्रामर को कार्य को आसान बनाने के लिए कॉन्फ़िगर करने की अनुमति देता है, और यह प्रोग्राम को कस्टम क्लासेस को जेनेरिक कोड (thats) से जोड़ने की क्षमता भी देता है। भाग मैं जीयूआई को अद्यतन किए बिना उन्हें वेब इंटरफ़ेस के माध्यम से उपयोग करने के लिए कौन से तरीकों को कॉन्फ़िगर करने की अनुमति देने के लिए, प्रतिबिंब का उपयोग करता हूं।
DGoiko

14

मेरे सहयोगी के जवाबों को पूरा करने के लिए, आप निम्नलिखित पर ध्यान देना चाहते हैं:

  • स्थिर या उदाहरण कॉल (एक मामले में, आपको कक्षा के उदाहरण की आवश्यकता नहीं है, दूसरे में, आपको मौजूदा डिफ़ॉल्ट निर्माणकर्ता पर भरोसा करने की आवश्यकता हो सकती है जो वहां हो सकती है या नहीं)
  • सार्वजनिक या गैर-सार्वजनिक विधि कॉल (उत्तरार्द्ध के लिए, आपको कॉल करने की आवश्यकता है विधि पर एक doPrivileged ब्लॉक के भीतर , अन्य खोजबिन्दु खुश नहीं होंगे )
  • यदि आप कई जावा सिस्टम अपवादों को वापस फेंकना चाहते हैं (तो नीचे दिए गए कोड में CCException)

यहाँ एक पुराना java1.4 कोड है जो उन बिंदुओं को ध्यान में रखता है:

/**
 * 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);

ऑब्जेक्ट में कम से कम मूल्य / मान होना चाहिए।
लोवा चित्तमुरी

यह वास्तव में अच्छी तरह से काम करने के लिए जो मुझे चाहिए था। मेरे पास एक वर्ग था जो पहले से ही तत्काल था और इसे बंद करने के लिए एक विधि की आवश्यकता थी। अपवादों के लिए कैच जोड़ना यहाँ एक अच्छा विचार है, लेकिन अन्यथा, यह मेरे लिए पूरी तरह से काम करता है। मुझे लगता है कि अशक्त अपवादों से बचने का मेरा तरीका अशक्तियों का उपयोग करना था, लेकिन मैं विधि नाम के एक बहुत ही सीमित सीमा का उपयोग कर रहा था (शाब्दिक रूप से केवल 1 से 4 तक काउंटर)।
जैन वाल्ड्रिप

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

यदि आप कई बार कॉल करते हैं तो आप जावा 7 में शुरू की गई नई पद्धति के हैंडल का उपयोग कर सकते हैं। यहां हम आपकी पद्धति के लिए एक स्ट्रिंग लौटाते हैं:

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
भविष्य के पाठकों के लिए; यदि आप प्रदर्शन के बारे में परवाह करते हैं invokeExactतो आप जब चाहें उपयोग कर सकते हैं। उसके लिए, कॉल साइट हस्ताक्षर को विधि संभाल प्रकार से मिलान करना होता है, हालांकि। यह आमतौर पर काम करने के लिए थोड़ा छेड़छाड़ करता है। इस मामले में आपको पहले पैरामीटर के साथ डालना होगा: methodHandle = methodHandle.asType(methodHandle.type().changeParameterType(0, Object.class));और फिर आह्वान करना होगा जैसेString result = (String) methodHandle.invokeExact(obj);
Jorn Vernee

7

यह कुछ ऐसा लगता है जो जावा रिफ्लेक्शन पैकेज के साथ आता है।

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

विशेष रूप से नाम से लागू करने के तरीके के तहत :

आयात 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

अनुक्रमण (तेज)

आप FunctionalInterfaceउन्हें अनुक्रमित करने के लिए एक कंटेनर में तरीकों को बचाने के लिए उपयोग कर सकते हैं। आप सरणी कंटेनर का उपयोग उन्हें संख्याओं या हैशमैप द्वारा उन्हें स्ट्रिंग द्वारा आह्वान करने के लिए कर सकते हैं। इस ट्रिक के द्वारा, आप अपने तरीकों को गतिशील रूप से तेज़ करने के लिए अनुक्रमित कर सकते हैं ।

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

लैम्ब्डा सिंटेक्स

आप लैम्ब्डा सिंटैक्स का भी उपयोग कर सकते हैं:

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
यह तकनीक परावर्तन से बहुत बेहतर लगती है।
जॉन ओ

क्या यह वास्तव में बहुत बेहतर है?
दिमित्री कोपरीवा

@DimitriKopriwa अनुक्रमण वह तरीका है जो आप CPU गणनाओं के बजाय RAM का उपयोग करते हैं। पूर्णांक अनुक्रमण के लिए, एल्गोरिथ्म की कठिनाई है O(1)
अमीर फेन

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

SomeClassवर्ग है और someVariableएक चर है।


अगर someVariable वास्तव में एक ऑब्जेक्ट है, तो someVariable.getClass () को कॉल करें। इसके अलावा, आप getMethod () को केवल तर्क के रूप में एक वर्ग के साथ नहीं बुला सकते हैं। न ही विधि के साथ आह्वान किया। सही: someVariable.getClass ()। GetMethod ("coolMethod", पैरामीटरassasses) .invoke (तर्क);
ओरेंजल


5

कृपया देखें निम्नलिखित कोड आपकी मदद कर सकता है।

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

धन्यवाद....


यह नहीं है कि आप जावा में स्ट्रिंग्स की तुलना कैसे करते हैं। आपको .equals मेथड का उपयोग करना चाहिए। अन्यथा, आप बस तुलना कर रहे हैं कि वे एक ही वस्तु संदर्भ हैं, और आप वास्तव में वस्तु संदर्भों के बारे में परवाह नहीं करते हैं - बस स्ट्रिंग सामग्री एक मैच है। आप प्रतिबिंब के माध्यम से नाम से भी विधि प्राप्त कर सकते हैं, इसलिए सुनिश्चित नहीं है कि आप अपना खुद का रोल क्यों करेंगे?
लो-टैन

5

यहाँ धातुओं का उपयोग करने के लिए पढ़ें:

तर्क के बिना, एक विधि लागू करने के लिए:

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

नीचे दिए गए तरीकों का उपयोग करें:

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

आउटपुट:

विधि ए  
विधि B:  
	परम १ - १  
	परम 2 - टेस्ट

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

आपको प्रतिबिंब का उपयोग करना चाहिए - एक वर्ग ऑब्जेक्ट को सम्मिलित करें, फिर इस कक्षा में एक विधि, और फिर वैकल्पिक मापदंडों के साथ किसी ऑब्जेक्ट पर इस विधि को लागू करें । निम्नलिखित स्निपेट को ट्राइ-कैच ब्लॉक में लपेटना याद रखें

आशा है ये मदद करेगा!

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

यह मेरे लिए ठीक काम कर रहा है:

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

}

आउटपुट:

My input testparam

मैं इसका नाम किसी अन्य विधि (जैसे मुख्य) पर पास करके विधि को लागू करने में सक्षम हूं।


1

का उपयोग करते हुए 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);
}

और यहां बताया गया है कि आप इसका उपयोग कैसे करते हैं:

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

0

जू के साथ यह केवल है:

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

यहाँ एक अधिक विस्तृत उदाहरण है:

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

यह प्रिंट:

3, 12, 1


-10

मेरे लिए एक बहुत ही सरल और मूर्ख सबूत तरीका बस एक विधि कॉलर विधि बनाना होगा जैसे:

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

तब जब आपको कॉल करने की आवश्यकता होती है, तो बस कुछ इस तरह से रखा जाए

//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
यदि उदाहरण पहले से ही संकलन के दौरान जाना जाता है, तो आप बस क्यों नहीं करते हैं className.getName().toString()? आप प्रतिबिंब के पूरे बिंदु को याद कर रहे हैं।
बालुसक

जैसा मैंने कहा, इस मामले में अनावश्यक है, लेकिन यह मानते हुए कि आप हमेशा जान पाएंगे कि उदाहरण एक बुरी प्रोग्रामिंग आदत है।
सुलैनी

2
@SMayne: मैं इस पोस्ट को हटाने का सुझाव दूंगा।
lpapp

खराब प्रोग्रामिंग इस मामले में एक तारीफ होगी
pdenti
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.