There are three approaches in Java.
1) Pass an object that has a method on it that provides the functionality that you need.
For example
new CronJob(3000, new Runnable() {
public void run() {
System.out.println("I ran");
}
});
Up to Java 8, that was pretty much the only option. After Java 8, we have two more approaches:
2) Use a lambda, which under the hood is really just syntactic sugar for creating an implementation of an interface with only one method on it.
new CronJob(3000, () -> System.out.println("I ran"));
One can read up on Lambdas here
Lambdas may take arguments, and they may also access fields and final variables from their declaring context. They are not full closures, so the variables must be effectively final which means that they do not need to be declared as final as the Java 8 compiler will figure it out for us.
For example:
public void scheduleJob( String name ) {
new CronJob(3000, () -> System.out.println("Hello "+name));
}
If one was using an interface whose method takes an argument, then it may look like this
public interface Job {
public void doJob( String arg );
}
public void scheduleJob() {
new CronJob(3000, arg -> System.out.println("Hello "+arg));
}
3) Pass an existing method by reference, for example
private void theTaskMethod() {
System.out.println("I ran");
}
new CronJob(3000, () -> this::theTaskMethod );
If one wants to use this approach with an interface whose method takes an argument, then the method reference must point to a method that also takes an argument of the same type. For example
If one was using an interface whose method takes an argument, then it may look like this
public interface Job {
public void doJob( String arg );
}
public void scheduleJob() {
new CronJob(3000, System.out::println); // would print out what ever arg was past to doJob(arg)
}