简体   繁体   中英

How do I call a method that has a method as its argument?

Here is a piece of code I have: (what I am trying to do with it is: define a method "renamingrule" in my main class, instantiate a instance of my other class "renamescript" and call its rename method passing as a parameter the "renamingrule" method i've defined in the main class. Everything is well in the RenamScript class, no errors, but i dont know how to call the rename method of the script class from my main class/method. thanks)

public class RenameScript2 {

    ...

    public void rename(Method methodToCall) throws IOException, IllegalAccessException, InvocationTargetException {


    try
    {
        ...

            String command = "cmd /c rename "+_path+"\\"+"\""+next_file+"\" "
                    +"\""+methodToCall.invoke(next_file, next_index)+"\"";
            p = Runtime.getRuntime().exec(command);

    }catch(IOException e1) {} catch(IllegalAccessException IA1) {}  catch(InvocationTargetException IT1) {} ;


    }//end of rename


} //end of class
//=======================================

public class RenameScriptMain2 {

    public static String RenamingRule(String input, int file_row)
    {
        String output = "renamed file "+(file_row+1)+".mp3";
        return output;
    }

    public static void main(String[] args) throws IOException
    {
        RenameScript2 renamer = new RenameScript2();
        renamer.setPath("c:\\users\\roise\\documents\\netbeansprojects\\temp\\files");
        try{
            renamer.rename(RenamingRule);
        }catch(IOException e2) {};

        System.out.println("Done from main()\n\n");

    }
} //end of class

You get hold of the Method object through Class.getMethod method. Something like this:

RenameScript2.class.getMethod("rename", parameters);

However, I suggest you consider writing an interface for a class that can perform the renaming, instead of passing a Method .

Such interface could look like

interface RenameAction {
    void performRename();
}

To wrap the script in a RenameAction object you would do something like

RenameAction action = new RenameAction() {
    void performRename() {
        // ...
        String command = "cmd /c rename "+_path+"\\"+"\""+next_file+"\" "...
        p = Runtime.getRuntime().exec(command);
        // ...
    }
};

You would then simply do like this:

public void rename(RenameAction action) {
    action.performRename();
}

Firstly, aioobe is definitely correct, passing a Method object is a little ugly. I'll assume that you're stuck with it!

To get a method, you'll need to usereflection . The below code grabs the method called toString on the class Integer . It then invokes the toString method.

Method method = Integer.class.getMethod("toString");
Object o = method.invoke(new Integer(7));
System.out.println(o);

Static methods don't need to pass the first parameter to method.invoke

Method method = File.class.getMethod("listRoots");
System.out.println(method.invoke(null));

This shows the reason why you shouldn't use it. That string "toString" and "listRoots" are not refactorable. If someone renames a method, then instead of a compile-time error, you'll get a runtime exception thrown (hence the exceptions you'll need to catch, NoSuchMethodException and IllegalAccessException ). It's also much slower to use reflection than to use normal code.

Here is how you should do:

  1. Make class RenameScript2 abstract by adding an abstract method public static String RenamingRule(String input, int file_row)
  2. Then have your main class RenameScriptMain2 extend above class RenameScript2 and provide implementation of the method RenamingRule() .
  3. Now inside main method create instance of the class RenameScriptMain2 and call method RenamingRule()

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