Can I pass a Method as parameter of another method in java?

前端 未结 6 476
隐瞒了意图╮
隐瞒了意图╮ 2021-01-04 21:04

I am trying to measure the execution time for several methods. so I was thinking to make a method instead of duplicate same code many times.

Here is my code:

相关标签:
6条回答
  • 2021-01-04 21:33

    Methods aren't first-class objects in Java, so they can't be passed as parameters. You could use wrap your method call in an annoymous class that extends e.g. the Runnable interface:

    private void MeasureExecutionTime(Runnable r) {
        r.run();
    }
    
    ...
    
    
    MeasureExecutionTime(new Runnable() { public void run() { m(); } });
    
    0 讨论(0)
  • 2021-01-04 21:34

    I have a object call Counter which basically looks like this:

    private long count;
    private long errors;
    private long duration;
    private long errorDuration;
    

    With two "time" methods for timing methods that return something and other methods which are void.

    public <T> T time(ReturningRunnable<T> runnable) {
        long start = currentTimeMillis();
        T result = null;
        try {
            result = runnable.run();
        } catch (Throwable ex) {
            errorDuration += currentTimeMillis() - start;
            errors++;
            throw runtime(ex);
        }
        duration += currentTimeMillis() - start;
        count++;
        return result;
    }
    
    public void time(Runnable runnable) {
        time(new RunnableRunner(runnable));
    }
    

    I chose to rethrow the exceptions as runtime exceptions (as i'm not a fan of checked exceptions) but you could just as well make your custom MyRunnable interface throw exceptions and just catch and re-throw them. Here's a usage of the above:

    counter.time(new Runnable() {
        @Override
        public void run() {
            // Do something
        });
    

    Or this, in the returning-value case:

    return counter.time(new ReturningRunnable<Integer>() {
        @Override
        public Integer run() {
            return 1; // You get the idea
        });
    

    I like this because my counter objects can be exposed over JMX and injected wherever i need them. You could do what you've asked with reflection, but i think that would be messy (IMHO).

    0 讨论(0)
  • 2021-01-04 21:38

    You are in the correct path, you need to pass the Method object, the target object on which to execute the method and the arguments it takes and then invoke it into your try catch, something like:

    private void MeasureExecutionTime(Method m, Object target, Object args) 
                                throws IllegalArgumentException, 
                                       IllegalAccessException, 
                                       InvocationTargetException
    {
        long startTime = System.nanoTime();
        long endTime;
        try
        {
            m.invoke(target, args);
        }
        finally
        {
            endTime = System.nanoTime();
        }
        long elapsedTime = endTime - startTime;
        System.out.println("This takes " + elapsedTime + " ns.");
    }
    
    0 讨论(0)
  • 2021-01-04 21:40

    you may do smth like:

    private void MeasureExecutionTime(Method m)
    {
    
        startTime = System.nanoTime();
        try
        {
            m.invoke(classObj, args);
        }
        finally
        {
            int endTime = System.nanoTime();
        }
        elapsedTime = endTime - startTime;
        System.out.println("This takes " + elapsedTime + " ns.");
    }
    
    0 讨论(0)
  • 2021-01-04 21:44

    the simplest way to do this is to pass an interface. So something like

    public interface CommonFuncs {
    
       public void execute();
       ... more functions
    
    }
    

    and then in you can have methods that take CommonFuncs as an argument. The implementations of those methods can call the execute method.

    0 讨论(0)
  • 2021-01-04 21:44

    I agree with @hvgotcodes, But yes, it is possible, though you don't call it like m(), but using invoke (which means that you probably should pass another argument or two with it...).

    0 讨论(0)
提交回复
热议问题