1

i'm making a CronJob function in java, seems like this:

public class CronJob {

    public static int mSeconds;
    public static String task; //?¿?¿

    public CronJob(int mSeconds, String task) {
        this.mSeconds = mSeconds;
        this.task = task;

        Timer timer = new Timer();

        timer.schedule(new TimerTask() {
            public void run() {
               //EJECUTE TASK
               //testFunction();
            }
        }, 0, mSeconds);
    }       
    ...
}

And in my main function I want to execute something like:

new CronJob(3000, testFunction());

I don't know how I can pass the name of the function to the CronJob class and which kind of variable I should use.

Thanks.

Dici
  • 25,226
  • 7
  • 41
  • 82
  • possible duplicate of [Java Pass Method as Parameter](http://stackoverflow.com/questions/2186931/java-pass-method-as-parameter) – mkazma Sep 21 '14 at 12:45

3 Answers3

1

You cannot pass a function as a parameter in Java. Instead, you need to pass an object of a known interface that implements the function of interest:

interface MyTask {
    void performTask();
}
...
public CronJob(int mSeconds, MyCallback task) {
    ...
}
...
public void run() {
   task.performTask();
}

In other words, you need to follow the same pattern that you use when you schedule a task with the timer, passing an instance of new TimerTask. Of course the implementation does not need to be anonymous. It is also not necessary to define your own interface for doing callbacks: you can reuse one of the interfaces available in Java class library, such as Runnable.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

You just need to use an interface for your task instead of a String. Runnable would be a good choice for you but if you need something more specific you can extend it or create your own interface.

Dici
  • 25,226
  • 7
  • 41
  • 82
0

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)
}
Chris K
  • 11,622
  • 1
  • 36
  • 49
  • If i use your 3º option, what kind of variable should i use in CronJob class to almacenate the second parameter? – Borja Sanchidrián Monge Sep 21 '14 at 12:41
  • @BorjaSanchidriánMonge the arguments have to line up with the interface, in my example I used Runnable which declared run(), a no arg argument. I will add another example which takes an argument. – Chris K Sep 21 '14 at 12:43
  • thanks, i just started programming in java yesterday and i'm a bit lost with this – Borja Sanchidrián Monge Sep 21 '14 at 12:45
  • @BorjaSanchidriánMonge you are welcome, the java eco system is very large and can be over whelming at first. The first approach is by far the most common approach in Java, and would be the first place the master. – Chris K Sep 21 '14 at 13:45