1

I'm trying to implement stopwatch class that will wrap all the required methods that i'm trying to measure

The main purpose is to create an framwork that when ever you want to measure the execution time of a method you will change the exiting code from:

<Classname> x = A();

or

A();

To:

<Classname> x = PSW.startWatch(MethodToWatch.B).invoke("123123123", A());

or

PSW.startWatch(MethodToWatch.B).invoke("123123123", A());

This is the code:

public class PerformanceStopWatch {
    private long start;
    private long end;
    private String uniqueID;
    private MethodToWatch methodName;

    public enum MethodToWatch {
        A,
        B
    }

    public PerformanceStopWatch startWatch(MethodToWatch methodName) {
        this.methodName = methodName;
        start();
        return this;
    }

    public void invoke(String uniqeID) {
        this.uniqueID = uniqeID;
        stop();
    }

    public void invoke(UUID machineId, void a) {
       invoke(machineId);
    }

    private void start() {
        start = System.nanoTime();
    }
    private void stop() {
        end = System.nanoTime();
        System.out.println("[PerformanceStopWatch|"+methodName.name()+"] - Unique ID: "+ uniqueID + " Took: <"+(end-start)+"> Nanosec");
    }
}

public void a() {
PerformanceStopWatch PSW = new PerformanceStopWatch();
..
..
..
PSW.startWatch(MethodToWatch.B).invoke("123123123", b());

}

public void b() {
...
...
..

}

The problem is that the compiler dose not allow me to use

public void invoke(UUID machineId, void a) {
    }

void is illegle type.

any idea?

beresfordt
  • 5,088
  • 10
  • 35
  • 43
USer22999299
  • 5,284
  • 9
  • 46
  • 78
  • It makes absolutely no sense to try to pass void to a method. Why are you trying that? – Tom Dec 01 '15 at 09:18
  • nevertheless no downvote candidate for me... – nano_nano Dec 01 '15 at 09:25
  • @Tom have you tried to read the question? i'm trying to measure the execution time of method b from method a – USer22999299 Dec 01 '15 at 09:25
  • @USer22999299 And you're doing it in a very ugly way. Please read this question for some inspiration: http://stackoverflow.com/questions/3382954/measure-execution-time-for-a-java-method – Tom Dec 01 '15 at 09:28
  • @Tom thanks, but i will try to ignor your advice. if you would like to help in here it would be nice, read the question before answering. – USer22999299 Dec 01 '15 at 09:30

3 Answers3

4

You can try Void insteed of void (Capital V) as the second one is not a type in strict sense. Void on the other hand is. But in general if you want to invoke with "void" you simply ommit arguments (talking about reflection here)

EDIT: to your comment

public void invoke(UUID machineId, Void a) { //note the capital V
   invoke(machineId);
}

Will compile just fine, but I dont see any usable usecase for such method signature.

Antoniossss
  • 31,590
  • 6
  • 57
  • 99
  • thanks! for your second part of the answer, how i can ommit the arguments and call it with void? – USer22999299 Dec 01 '15 at 09:16
  • invoke(UUID machineId, Void... a) – Roger Dwan Dec 01 '15 at 09:18
  • while changing it to public void invoke(UUID machineId, Void a), and using is as .PSW.startWatch(MethodToWatch.B).invoke("123123123", b()); i'm still getting "wrong 2nd arrgument type found "void" required "java.lang.Void" – USer22999299 Dec 01 '15 at 09:23
  • @USer22999299 pass `null` insteed of `b()` You must undestand that `void` in general is not a type but declaration that function does not return a value. `Void` is private dummy type introduce for generics. – Antoniossss Dec 01 '15 at 09:24
  • @USer22999299 Please do yourself a favor and just use `b(); PSW.startWatch(MethodToWatch.B).invoke("123123123");`. What your trying to do is _very_ ugly code. – Tom Dec 01 '15 at 09:25
  • @Antoniossss this is not the case, we are trying to create a framwork that will be use in a lot of places in the code, the idea is to start the stop watch and invoke the method. we are trying to make it this way that ppl wont do any mistakes and in case they will change it it will be clear what they are doing. – USer22999299 Dec 01 '15 at 09:28
  • @Tom thanks for your kindly advice, but you are not helping. – USer22999299 Dec 01 '15 at 09:28
  • 1
    @USer22999299 Simply speaking, you cannot pass void as argument that would be different than null. – Antoniossss Dec 01 '15 at 10:00
3

It looks like you want to pass a method to the invoke() method. Since the method you are passing returns nothing and has no arguments, you should use Runnable interface :

public void invoke(UUID machineId, Runnable a) {
   invoke(machineId);
   a.run();
}

and

PSW.startWatch(MethodToWatch.B).invoke("123123123", () -> {b();});

or (if you are not using Java 8) :

PSW.startWatch(MethodToWatch.B).invoke("123123123",
                                       new Runnable() {
                                             public void run() {
                                               b();
                                             }
                                       });
Eran
  • 387,369
  • 54
  • 702
  • 768
  • cool! and in case the method will return int / string, is there an option as well to use it? – USer22999299 Dec 01 '15 at 09:17
  • @USer22999299 There are all kinds of functional interfaces added in Java 8. For example, `IntSupplier` has a single method that returns an `int`. – Eran Dec 01 '15 at 09:18
  • Thanks, this one solved my issue, in case you need a return value you can consider using the callable interface insted of the runable :) – USer22999299 Dec 01 '15 at 14:13
1

What exactly do you want to do? There are no objects or values of type void, so if it would have been allowed, you would not be able to call the method.

Maybe what you want is to be able to pass an object of any type. In this case you can use Object:

public void invoke(UUID machineId, Object a) {
    invoke(machineId);
}

Since every class is a subclass of Object, now you can pass any object as the second argument to this method, including arrays. You can also pass primitive types (they will be wrapped to their corresponding wrapper class).

Hoopje
  • 12,677
  • 8
  • 34
  • 50
  • I would like to measure the time of calling method b as i wrote in the question – USer22999299 Dec 01 '15 at 09:25
  • @USer22999299. Yes, that is what you want to do with the class. But what purpose does that method have? It takes an argument `a` but just ignores it. – Hoopje Dec 01 '15 at 09:30
  • the purpose is to build a framwork and a patern that when ever you want to masure the time of a method, this is what you have to do regardless of what this method is returning. – USer22999299 Dec 01 '15 at 09:35