Java Pass Method as Parameter

后端 未结 16 998
滥情空心
滥情空心 2020-11-22 02:17

I am looking for a way to pass a method by reference. I understand that Java does not pass methods as parameters, however, I would like to get an alternative.

I\'ve

相关标签:
16条回答
  • 2020-11-22 02:51

    Edit: as of Java 8, lambda expressions are a nice solution as other answers have pointed out. The answer below was written for Java 7 and earlier...


    Take a look at the command pattern.

    // NOTE: code not tested, but I believe this is valid java...
    public class CommandExample 
    {
        public interface Command 
        {
            public void execute(Object data);
        }
    
        public class PrintCommand implements Command 
        {
            public void execute(Object data) 
            {
                System.out.println(data.toString());
            }    
        }
    
        public static void callCommand(Command command, Object data) 
        {
            command.execute(data);
        }
    
        public static void main(String... args) 
        {
            callCommand(new PrintCommand(), "hello world");
        }
    }
    

    Edit: as Pete Kirkham points out, there's another way of doing this using a Visitor. The visitor approach is a little more involved - your nodes all need to be visitor-aware with an acceptVisitor() method - but if you need to traverse a more complex object graph then it's worth examining.

    0 讨论(0)
  • 2020-11-22 02:52

    Here is a basic example:

    public class TestMethodPassing
    {
        private static void println()
        {
            System.out.println("Do println");
        }
    
        private static void print()
        {
            System.out.print("Do print");
        }
    
        private static void performTask(BasicFunctionalInterface functionalInterface)
        {
            functionalInterface.performTask();
        }
    
        @FunctionalInterface
        interface BasicFunctionalInterface
        {
            void performTask();
        }
    
        public static void main(String[] arguments)
        {
            performTask(TestMethodPassing::println);
            performTask(TestMethodPassing::print);
        }
    }
    

    Output:

    Do println
    Do print
    
    0 讨论(0)
  • 2020-11-22 02:54

    Use the java.lang.reflect.Method object and call invoke

    0 讨论(0)
  • 2020-11-22 02:54

    Use the Observer pattern (sometimes also called Listener pattern):

    interface ComponentDelegate {
        void doSomething(Component component);
    }
    
    public void setAllComponents(Component[] myComponentArray, ComponentDelegate delegate) {
        // ...
        delegate.doSomething(leaf);
    }
    
    setAllComponents(this.getComponents(), new ComponentDelegate() {
                                                void doSomething(Component component) {
                                                    changeColor(component); // or do directly what you want
                                                }
                                           });
    

    new ComponentDelegate()... declares an anonymous type implementing the interface.

    0 讨论(0)
  • 2020-11-22 02:54

    I appreciate the answers above but I was able to achieve the same behavior using the method below; an idea borrowed from Javascript callbacks. I'm open to correction though so far so good (in production).

    The idea is to use the return type of the function in the signature, meaning that the yield has to be static.

    Below is a function that runs a process with a timeout.

    public static void timeoutFunction(String fnReturnVal) {
    
        Object p = null; // whatever object you need here
    
        String threadSleeptime = null;
    
        Config config;
    
        try {
            config = ConfigReader.getConfigProperties();
            threadSleeptime = config.getThreadSleepTime();
    
        } catch (Exception e) {
            log.error(e);
            log.error("");
            log.error("Defaulting thread sleep time to 105000 miliseconds.");
            log.error("");
            threadSleeptime = "100000";
        }
    
        ExecutorService executor = Executors.newCachedThreadPool();
        Callable<Object> task = new Callable<Object>() {
            public Object call() {
                // Do job here using --- fnReturnVal --- and return appropriate value
                return null;
            }
        };
        Future<Object> future = executor.submit(task);
    
        try {
            p = future.get(Integer.parseInt(threadSleeptime), TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            log.error(e + ". The function timed out after [" + threadSleeptime
                    + "] miliseconds before a response was received.");
        } finally {
            // if task has started then don't stop it
            future.cancel(false);
        }
    }
    
    private static String returnString() {
        return "hello";
    }
    
    public static void main(String[] args) {
        timeoutFunction(returnString());
    }
    
    0 讨论(0)
  • 2020-11-22 02:55

    Last time I checked, Java is not capable of natively doing what you want; you have to use 'work-arounds' to get around such limitations. As far as I see it, interfaces ARE an alternative, but not a good alternative. Perhaps whoever told you that was meaning something like this:

    public interface ComponentMethod {
      public abstract void PerfromMethod(Container c);
    }
    
    public class ChangeColor implements ComponentMethod {
      @Override
      public void PerfromMethod(Container c) {
        // do color change stuff
      }
    }
    
    public class ChangeSize implements ComponentMethod {
      @Override
      public void PerfromMethod(Container c) {
        // do color change stuff
      }
    }
    
    public void setAllComponents(Component[] myComponentArray, ComponentMethod myMethod) {
        for (Component leaf : myComponentArray) {
            if (leaf instanceof Container) { //recursive call if Container
                Container node = (Container) leaf;
                setAllComponents(node.getComponents(), myMethod);
            } //end if node
            myMethod.PerfromMethod(leaf);
        } //end looping through components
    }
    

    Which you'd then invoke with:

    setAllComponents(this.getComponents(), new ChangeColor());
    setAllComponents(this.getComponents(), new ChangeSize());
    
    0 讨论(0)
提交回复
热议问题