java 我可以在java中将方法作为另一个方法的参数传递吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6061049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I pass a Method as parameter of another method in java?
提问by Eng.Fouad
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:
这是我的代码:
private void MeasureExecutionTime(Method m)
{
startTime = System.nanoTime();
try
{
m();
}
finally
{
endTime = System.nanoTime();
}
elapsedTime = endTime - startTime;
System.out.println("This takes " + elapsedTime + " ns.");
}
Suppose I have myMethod()
, how can I use MeasureExecutionTime()
to measure myMethod
's execution time?
假设我有myMethod()
,我如何使用MeasureExecutionTime()
来衡量myMethod
的执行时间?
采纳答案by Oliver Charlesworth
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:
方法不是 Java 中的一等对象,因此它们不能作为参数传递。您可以使用将您的方法调用包装在一个扩展例如Runnable
接口的讨厌的类中:
private void MeasureExecutionTime(Runnable r) {
r.run();
}
...
MeasureExecutionTime(new Runnable() { public void run() { m(); } });
回答by hvgotcodes
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.
然后在你可以有将 CommonFuncs 作为参数的方法。这些方法的实现可以调用该execute
方法。
回答by MByD
回答by Miquel
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:
您位于正确的路径中,您需要传递 Method 对象、执行该方法的目标对象以及它所采用的参数,然后将其调用到您的 try catch 中,例如:
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.");
}
回答by alpian
I have a object call Counter which basically looks like this:
我有一个对象调用 Counter,它基本上是这样的:
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:
我选择将异常作为运行时异常重新抛出(因为我不喜欢检查异常),但您也可以让自定义 MyRunnable 接口抛出异常,然后捕获并重新抛出它们。这是上面的用法:
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).
我喜欢这样,因为我的计数器对象可以通过 JMX 公开并注入到我需要的任何地方。你可以用反射做你问过的事情,但我认为那会很麻烦(恕我直言)。
回答by birdy
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.");
}