java - स्ट्रिंग के रूप में विधि नाम दिए जाने पर मैं जावा विधि का उपयोग कैसे करूं?




reflection invoke (12)

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

Object obj;
String methodName = "getName";

obj की कक्षा को जानने के बिना, मैं विधि विधि द्वारा पहचाने गए विधि को कैसे कॉल कर सकता हूं?

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


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

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

आशा करता हूँ की ये काम करेगा!

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

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

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

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

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

पैरामीटर आपको आवश्यक विशिष्ट विधि की पहचान करते हैं (यदि कई ओवरलोडेड उपलब्ध हैं, यदि विधि में कोई तर्क नहीं है, तो केवल विधि नाम दें)।

फिर आप कॉल करके उस विधि का आह्वान करते हैं

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

दोबारा, यदि आपके पास कोई नहीं है, तो .invoke में तर्क छोड़ दें। लेकिन हाँ। जावा प्रतिबिंब के बारे में पढ़ें


प्रतिबिंब से विधि आमंत्रण का प्रयोग करें:

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[] प्रकार का है और विधि को पारित करने के लिए पैरामीटर घोषित करता है

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

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

मैं ऐसा करता हूं:

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

यदि आप कई बार कॉल करते हैं तो आप जावा 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]

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

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



}

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

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


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

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

SomeClass कक्षा है और कुछ उपलब्ध एक चर है।







invoke