gcoulby
gcoulby

Reputation: 544

Can I use an If statement to check which method made the call?

I want to make an if statement that checks to see which method made the call to a secondary method.

I will write what i want in pseudo code so you can see what I mean.

public static void methodOne() {
    methodToCall();
    }

public static void methodTwo() {
    methodToCall();
    }

public static void methodThree() {
    methodToCall();
    }

public static void methodToCall() {
    if (methodOne made the call == true) {
        execute this
    } else if (methodTwo made the call == true){
        execute this
    } else if (methodThree made the call == true){
        execute this
    } else {
        System.out.println("How did you get here?");
    }
}

That's about the gist of it. I want a simple check to see which method made the call so I can choose which operation is relevant to the call.

Is this possible?

If it is not possible, is there a work around?

Upvotes: 1

Views: 3164

Answers (5)

siledh
siledh

Reputation: 3378

If you end up using an enum, then make sure to take advantage of the fact that enums in Java are no less than singleton instances of classes. Therefore you can declare the method as abstract in the enum definition and then override it in each instance, instead of passing the enum as a paramater to some method defined outside of the enum's context.

So it would look something like:

enum Method {

    Mode1 {
            @Override
            void call() {
                    // do stuff 
            }
    }, Mode2 {
            @Override
            void call() {
                    // do stuff differently
            }
    }, Mode3 {
            @Override
            void call() {
                    // do stuff even more differently
            }
    };

    abstract void call();
}

And then you either don't need your wrapping methods, or, if they were supposed to do anything more, you write:

public static void methodOne() {
    // some code
    Method.Mode1.call();
    // some code
}

Upvotes: 1

Bohemian
Bohemian

Reputation: 425238

You can do it by examining the call stack via Thread.getStackTrace():

public static void methodToCall(Action action) {
    String callingMethod = Thread.currentThread().getStackTrace()[2].getMethodName();
    if (callingMethod.equals("methodOne")) {
        execute this0
    } else if (callingMethod.equals("methodTwo")) {
        execute this
    } else if (callingMethod.equals("methodThree")) {
        execute this
    } else {
        System.out.println("How did you get here?");
    }
}

but you shouldn't - it's a bit anti-OO. Instead, change your method signature to something like this:

public enum Action {ONE, TWO, THREE}

public static void methodToCall(Action action) {
    if (action == ONE) {
        execute this
    } else if (action == TWO) {
        execute this
    } else if (action == THREE) {
        execute this
    } else {
        System.out.println("How did you get here?");
    }
}

Upvotes: 2

Kevin Bowersox
Kevin Bowersox

Reputation: 94499

Use three short methods, instead of combining the logic of three short methods into one larger method. Once the short methods are created Just call the appropriate method from each calling method.

public static void methodOne() {
    methodToCall1();
}

public static void methodTwo() {
    methodToCall2();
}

public static void methodThree() {
    methodToCall3();
}

public static void methodToCall1() {
    int x = 0;
    x = x - 3; //some custom logic to prep argument
    commonLogic(x);
}

public static void methodToCall2() {
    //Method 2 logic
    int x = 0;
    x = x + 3; //some custom logic to prep argument
    commonLogic(x);
}

public static void methodToCall3() {
    //Method 3 logic
    int x = 0;
    x = x * 3; //some custom logic to prep argument
    commonLogic(x);
}

public static void commonLogic(int arg1){
     //peform common logic
}

If these three methods would contain duplicate code, abstract the duplicate code into another method then call that method from within each of the smaller methods. The idea is to prepare the arguments to call the common function in each of the three smaller functions, then call the common function with those arguments.

Upvotes: 4

user207421
user207421

Reputation: 310979

This is called 'state orientation', and it was debated extensively in the 1970s, possibly even the 1960s. The conclusion was that if you need to know this sort of thing you are already doing something seriously wrong, by introducing a two-way dependency into the code. What happens for example when you add another caller?

Upvotes: 5

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726889

A great deal of the abstraction afforded by methods comes from the fact that they do not need to know who is calling them, so the answer to your question is "no". It does not mean that you cannot make it work, though: make the callers pass some sort of a token (say, an enum value) identifying themselves to the callee. This would let you dispatch on that identity inside your method's implementation:

enum CallerContext {CALLER1, CALLER2, CALLER3};
...
public static void methodToCall(CallerContext context) {
    ...
}

This is not the most Object-Oriented way of doing things, however: very often, a better approach would be letting the callers supply the logic to be executed, rather than supplying a token identifies that logic. See Visitor Pattern for details on that approach.

Upvotes: 4

Related Questions