简体   繁体   中英

Java invoke method using reflection

I am trying to invoke a method using reflection.

The method I am invoking is not static and in the same class I am invoking it from.

A simplified version of my code:

public class Test {
  public static void main(String[] args) {
    Test instance = new Test();
    if (args.length > 0) {
      instance.doWork(args[0]);
    }
  }

  private void doWork(String methodName) {
    Method method;

    try {
      method = this.getClass().getMethod(methodName);
      method.invoke(this);
    } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
      [...]
    }
  }

  private void MethodOne() { ... };
  private void MethodTwo() { ... };
  [...]
  private void MethodTwenty() { ... };
}

What I am getting is a java.lang.NoSuchMethodException: correct.package.and.class.MethodTwo() despite the package / class / method existing.

Can someone tell me what I am doing wrong?

What I am getting is a java.lang.NoSuchMethodException: correct.package.and.class.MethodTwo()...

you are calling the getMethod() which is not giving back the private method

Assuming that arg[0] has the right name of the method (if not you'll get a java.lang.NoSuchMethodException again), 2 thing must be done here:

  1. you need to use getDeclaredMethod (because MethodOne is private declared)

  2. your need to set the flag for access to it .setAccessible(true) (this will allow you to invoke a method that is declared private)

Example:

    Method method;
    try {
        method = f.getClass().getDeclaredMethod("doThis");

        method.setAccessible(true);
        method.invoke(f);
    } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
            | InvocationTargetException e) {
        System.err.println("Opala, somethign went wrong here!");
    } 

The way you are accessing method is correct. The method access specifier is private. Thus it is throwing error.

Please change the access specifier to public , it will work.

import java.lang.reflect.Method;

public class Test {
  public static void main(String[] args) {
    Test instance = new Test();
    if (args.length > 0) {
      instance.doWork(args[0]);
    }
  }

  private void doWork(String methodName) {
    Method method;

    try {
      method = this.getClass().getMethod(methodName);
      method.invoke(this);
    } catch (Exception e) {

    }
  }

  public void MethodOne() { System.out.println("Method 1"); };
  public void MethodTwo() { System.out.println("Method 2"); };
  public void MethodTwenty() { System.out.println("Method 3"); };
}

If you are trying to access private methods or constructors, you need to change the code.

Thanks, Thiruppathi S

CLASS TO INVOKE METHODS FROM

public class Computer {

private String brandName;
private int yearManufactured;

public String getBrandName() {
    return brandName;
 }

public void setBrandName(String brandName) {
    this.brandName = brandName;
 }

public int getYearManufactured() {
    return yearManufactured;
 }

public void setYearManufactured(int yearManufactured) {
    this.yearManufactured = yearManufactured;
 }

}

IMPLEMENTATION CLASS

public class Test {

public static void main(String[] args) throws NoSuchMethodException,  
        InvocationTargetException, IllegalAccessException{
          
    Class curClass = Computer.class;
    Method[] allMethods = curClass.getDeclaredMethods();
    
    Computer myComputer = new Computer();
          
    for(int c = 0; c < allMethods.length; c++){
             
        Class[] parameterTypes = allMethods[c].getParameterTypes();           
        for(Class parameterType: parameterTypes){
           
           System.out.println(parameterType.getName());                
           
           switch(parameterType.getName()){
           
               case "java.lang.String":                     
                   allMethods[c].invoke(myComputer, "LENOVO");
               break;
               
               case "int":        
                   allMethods[c].invoke(myComputer, 2021);
               break;               
           }
        }                 
    }
    
    System.out.println("BRAND NAME :"+myComputer.getBrandName());
    System.out.println("YEAR MANUFACTURED: "+myComputer.getYearManufactured());

  }
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM