1

我想做一个 if 语句来检查哪个方法调用了辅助方法。

我将用伪代码编写我想要的内容,以便您了解我的意思。

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?");
    }
}

这就是它的要点。我想要一个简单的检查来查看调用的方法,以便我可以选择与调用相关的操作。

这可能吗?

如果不可能,是否有解决方法?

4

5 回答 5

5

这被称为“国家导向”,在 1970 年代,甚至可能在 1960 年代,它被广泛讨论。结论是,如果你需要知道这类事情,你已经在做一些严重错误的事情,通过在代码中引入双向依赖。例如,当您添加另一个呼叫者时会发生什么?

于 2013-09-29T10:31:00.860 回答
4

方法提供的大量抽象来自于它们不需要知道谁在调用它们的事实,因此您的问题的答案是“不”。但是,这并不意味着您不能让它工作:让调用者将某种标记(例如,一个enum值)传递给被调用者。这将允许您在方法的实现中分派该身份:

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

然而,这不是最面向对象的做事方式:通常,更好的方法是让调用者提供要执行的逻辑,而不是提供标识该逻辑的令牌。有关该方法的详细信息,请参阅访客模式

于 2013-09-29T10:23:30.363 回答
4

使用三个短方法,而不是将三个短方法的逻辑组合成一个更大的方法。创建短方法后,只需从每个调用方法中调用适当的方法即可。

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
}

如果这三个方法包含重复代码,则将重复代码抽象为另一个方法,然后从每个较小的方法中调用该方法。这个想法是准备参数以在三个较小函数中的每一个中调用公共函数,然后使用这些参数调用公共函数。

于 2013-09-29T10:16:55.750 回答
2

您可以通过检查调用堆栈来做到这一点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?");
    }
}

但你不应该 - 这有点反 OO。相反,将您的方法签名更改为如下所示:

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?");
    }
}
于 2013-09-29T10:40:40.030 回答
1

如果您最终使用枚举,那么请确保利用 Java 中的枚举不亚于类的单例实例这一事实。因此,您可以在枚举定义中将该方法声明为抽象,然后在每个实例中覆盖它,而不是将枚举作为参数传递给在枚举上下文之外定义的某个方法。

所以它看起来像:

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();
}

然后你要么不需要你的包装方法,要么,如果他们应该做更多的事情,你写:

public static void methodOne() {
    // some code
    Method.Mode1.call();
    // some code
}
于 2013-09-29T12:40:01.293 回答