স্ট্রিং হিসাবে পদ্ধতির নাম দেওয়া হলে আমি কীভাবে জাভা পদ্ধতিতে প্রার্থনা করব?


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
মেলা নয় -১। হেনরিক সম্ভবত স্কোয়াশিং ব্যতিক্রমের পক্ষে পরামর্শ দিচ্ছেন না এবং তাদের জন্য কিছু লেখেননি কারণ তিনি কেবল প্রতিবিম্ব প্রদর্শন করার চেষ্টা করছেন।
সৃষ্টি

70
কিছু সম্ভাব্য ব্যতিক্রম দেখানোর জন্য প্লাস ওয়ান। আমি যদি এটি লিখে
রাখতাম

1
আমি পেয়েছিলাম জন্য "পরিবর্তনশীল সক্রিয়া করা হয়েছে নাও করতে পারে" methodমধ্যে method.invoke(obj, arg1, arg2,...);। একটি সমস্যার method = null;সমাধান করে তবে উত্তরে এর উল্লেখ করা কোনও খারাপ ধারণা নয়।
আমিন

2
@ ডিএমন 1 জাভা পদ্ধতিগুলি "প্রস্থান কোডগুলি" ব্যবহার করে না, তবে পদ্ধতিটি যদি কোনও কিছু ফেরত দেয় তবে 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 চেয়ে 'নিরাপদ' () .. হয়
brasskazoo

22
ভুল। হ্যাঁ, getDeclaredMethod ব্যক্তিগত এবং সুরক্ষিত পদ্ধতিগুলির সাথে কাজ করে। বাট: এটি সুপার ক্লাসে বর্ণিত পদ্ধতিগুলির সাথে কাজ করে না (উত্তরাধিকার সূত্রে প্রাপ্ত পদ্ধতি)। সুতরাং, আপনি কী করতে চান তা এটি দৃ strongly়ভাবে নির্ভর করে। অনেক ক্ষেত্রে আপনি পদ্ধতিটি সংজ্ঞায়িত হওয়া সঠিক শ্রেণীর নির্বিশেষে এটি কাজ করতে চান।
jrudolph

এবং আমার "ক্লাস" ফাইলটি কোথায় রাখা উচিত?
অগ্রণীভাবে

@ মিঃ হাইড ক্লাসের পথে।
স্টিজন ডি উইট

আমি কী পদ্ধতিতে কল করছি এবং পদ্ধতি.invoke () এর ভিতরে আমার কী রাখা উচিত যদি কোনও পরামিতি গ্রহণ না করে? মনে হচ্ছে আমাকে এখনও দ্বিতীয় প্যারামিটার সরবরাহ করতে হবে, এটি কিছু খালি অবজেক্ট অ্যারে হওয়া উচিত?
ইগোর

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আপত্তি পাবেন?
parlad

প্রতিবিম্ব 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

প্রথম, না। এই ধরণের কোড এড়িয়ে চলুন। এটি আসলেই খুব খারাপ কোড এবং অনিরাপদ হতে থাকে ( জাভা প্রোগ্রামিং ভাষার জন্য সুরক্ষিত কোডিং গাইডলাইনস এর বিভাগ 6 দেখুন , সংস্করণ 2.0 )।

যদি এটি অবশ্যই করতে হয়, java.beans প্রতিবিম্ব করতে পছন্দ করুন। বিনগুলি তুলনামূলকভাবে নিরাপদ এবং প্রচলিত অ্যাক্সেসের অনুমতি দেয় প্রতিচ্ছবি মোড়ক করে।


11
আমি একমত নই সুরক্ষিত থাকার জন্য এই জাতীয় কোড লেখা খুব সহজ এবং আমি একাধিক ভাষায় এটি করেছি। উদাহরণস্বরূপ, কেউ অনুমতিযোগ্য পদ্ধতির একটি সেট তৈরি করতে পারে, এবং কেবল কোনও পদ্ধতির নাম সেট করা থাকলে সেগুলি চালিত করার অনুমতি দেয়। আরও সুরক্ষিত (তবুও হাড়ের মাথার সরল) প্রতিটি অনুমোদিত পদ্ধতি একটি নির্দিষ্ট অবস্থায় সীমাবদ্ধ করে দেওয়া হবে এবং থ্রেড / ইন্টারফেস / ব্যবহারকারী / যে কোনও মানদণ্ডের সাথে মানানসই না হওয়া অবধি পদ্ধতিটি চালু করা দেওয়া হবে না।
জেএসএন

এ জাতীয় সমস্যা সম্পর্কে কখনই শ্রেণীবদ্ধ হতে হবে না। এই মুহুর্তে আমি একটি সাধারণ প্রোগ্রাম তৈরি করছি যা ব্যবহারকারীকে ওয়েব ইন্টারফেস ব্যবহার করে স্বেচ্ছাসেবী বিষয়গুলির উপর স্বেচ্ছাসেবী কার্যগুলি সংজ্ঞায়িত করতে দেয়। আমি জানি এটি প্রকৃতপক্ষে অনিরাপদ, তবে কনফিগারেশনটি গ্রহণের পরে যথাযথ পরীক্ষা করা হয় এবং এটি কোনও নন-প্রোগ্রামারকে কাজগুলি কনফিগার করতে ইজিলিকে অনুমতি দেয় এবং প্রোগ্রামগুলিকে জেনেরিক কোডের সাথে কাস্টম ক্লাসগুলি সংযুক্ত করার ক্ষমতা দেয় (ততক্ষণে অংশটি আমি জিইআইআই আপডেট না করে ওয়েব প্রতিযোগিতার মাধ্যমে কোন পদ্ধতিটি ব্যবহার করতে হবে তা কনফিগার করার অনুমতি দেওয়ার জন্য প্রতিচ্ছবি ব্যবহার করি।
ডিজিওকো

14

আমার সহকর্মীর উত্তরগুলি সম্পূর্ণ করতে, আপনি নিবিড় মনোযোগ দিতে চান:

  • স্থিতিশীল বা উদাহরণ কল (এক ক্ষেত্রে আপনাকে শ্রেণীর উদাহরণের দরকার নেই, অন্যথায় আপনাকে কোনও বিদ্যমান ডিফল্ট কনস্ট্রাক্টরের উপর নির্ভর করতে হবে করতে হবে যা সেখানে থাকতে পারে বা নাও হতে পারে)
  • সর্বজনীন বা অ-পাবলিক পদ্ধতি কল (দ্বিতীয়টির জন্য, আপনাকে doPrivileged ব্লকের মধ্যে থাকা পদ্ধতিটিতে সেটঅ্যাক্সেসেবল কল করতে হবে , অন্যান্য ফাইন্ডব্যাগগুলি খুশি হবে না )
  • আপনি যদি আরও অনেক জাভা সিস্টেম ব্যতিক্রম পিছনে ফেলে দিতে চান তবে আরও একটি পরিচালনাযোগ্য প্রয়োগমূলক ব্যতিক্রমকে আবদ্ধ করুন (সুতরাং নীচের কোডটিতে সিসিই এক্সেকশন)

এখানে একটি পুরানো জাভা ১.৪ কোড রয়েছে যা এই পয়েন্টগুলিকে বিবেচনা করে:

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

আপনি যদি বেশ কয়েকবার কল করেন তবে আপনি জাভা introduced তে প্রবর্তিত নতুন পদ্ধতি হ্যান্ডলগুলি ব্যবহার করতে পারেন Here এখানে আমরা আপনার স্ট্রিংটি ফেরানোর পদ্ধতিটির জন্য যাচ্ছি:

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);
অনুরোধ করুন

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
এই কৌশলটি প্রতিবিম্বের চেয়ে অনেক ভাল বলে মনে হচ্ছে।
জন হে

এটা কি আসলে অনেক ভাল?
দিমিত্রি কোপ্রিভা

@ দিমিত্রিকোপ্রিভা ইনডেক্সিং সিপিইউ গণনার পরিবর্তে আপনি যেভাবে র্যাম ব্যবহার করেন তা। পূর্ণসংখ্যার সূচকের জন্য, অ্যালগরিদমের অসুবিধা O(1)
আমির ফো

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

SomeClassবর্গ এবং someVariableএকটি পরিবর্তনশীল।


যদি কিছু ভেরিয়েবল সত্যিই কোনও অবজেক্ট হয় তবে কিছুটি পরিবর্তনশীল.জেটক্লাস () কল করুন। এছাড়াও, আপনি একমাত্র যুক্তি হিসাবে ক্লাস সহ getMethod () কল করতে পারবেন না। উভয়ই পদ্ধতিতে অনুরোধ করুন। সংশোধন করুন: someVariable.getClass ()। GetMethod ("coolMethod", প্যারামিটারক্লাস)। ইনভেক (আর্গুমেন্ট);
এঙ্গেল

5

আমি এটি এইভাবে করি:

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

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

ধন্যবাদ ....


আপনি জাভাতে স্ট্রিংগুলি কীভাবে তুলনা করছেন তা এটি নয়। আপনার অবশ্যই .aquals পদ্ধতি ব্যবহার করা উচিত। অন্যথায়, আপনি কেবল তুলনা করছেন যে সেগুলি একই বস্তুর রেফারেন্স, এবং আপনি আসলে অবজেক্ট রেফারেন্সের বিষয়ে চিন্তা করেন না - কেবল স্ট্রিংয়ের বিষয়বস্তু মিলছে। আপনি প্রতিবিম্বের মাধ্যমে নামটিও পদ্ধতিটি পেতে পারেন, সুতরাং আপনি নিজের রোল করবেন না কেন তা নিশ্চিত নন?
লো-ট্যান

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

আউটপুট:

পদ্ধতি এ  
পদ্ধতি বি:  
	পরম 1 - 1  
	পরম 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

আপনার প্রতিবিম্ব ব্যবহার করা উচিত - আর ডি ক্লাস অবজেক্ট, তারপরে এই ক্লাসের একটি পদ্ধতি এবং তারপরে al চ্ছিক পরামিতিগুলির সাথে কোনও অবজেক্টে এই পদ্ধতিটি চাওয়া। চেষ্টা করুন- ব্লক নিম্নলিখিত স্নিপেট মোড়ানো মনে রাখবেন

আশা করি এটা সাহায্য করবে!

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

সঙ্গে jooR নিছক আছে:

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
@ এসমায়েন: আমি এই পোস্টটি মুছে ফেলার পরামর্শ দেব।
lpapp

খারাপ প্রোগ্রামিং বরং এই ক্ষেত্রে একটি প্রশংসা হবে
pdenti
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.