有没有一种好方法可以知道某个方法是由父母还是其他地方调用的?

时间:2017-12-11 00:12:43

标签: java inheritance

我有以下代码,其目标是当在父项上调用方法时,它会在所有子项上调用相同的方法,这就是实际工作完成的地方。

public class Parent {

    Child[] children;

    public doWork() {
        for(int i = 0; i < children.size(); i++) //For all my children
            children.get(i).dowork();            //Call the same method
        Log.ReportWorkBeingDone(this);           //Report this has happened
    }
}

public class Child extends Parent{

    @override
    public doWork() {
        //Actual Work                            //Run the actual code
        Log.ReportWorkBeingDone(this);           //Report this has happened
    }
}

现在,在父级调用doWork()时,Log类从Parent获取方法调用,然后从其中的每个Child对象调用一次阵列。

是否有编程模式或只是一次只运行Log类调用的好方法?因此,如果从这个类链外部调用Child doWork(),那么子将调用Log方法,但如果在父类上调用doWork(),则父类将调用Log 1}}方法和孩子不会?

我能想到的就是这样的事情:

public class Parent {

    Child[] children;

    public doWork() {
        sneakyHiddenWork();
        Log.ReportWorkBeingDone(this);                     //Report this has happened
    }

    protected sneakyHiddenWork(){
        for(int i = 0; i < children.size(); i++)           //For all my children
            children.get(i).sneakyHiddenWork();            //Call the same method
    }

}

public class Child extends Parent{

    @override
    protected sneakyHiddenWork() {
        //Actual Work                                      //Run the actual code
    }
}

1 个答案:

答案 0 :(得分:2)

您的解决方案(sneakyHiddenWork)是最佳解决方案......尽管您选择的名称缺少重点。 (这不是“鬼鬼祟祟”。做这种事情是一种常见的模式。)

是的,可以找出调用方法的名称是什么,但在Java 1 中没有很好地支持,并且该过程昂贵 。您实例化一个异常对象,然后查看由Throwable::getStackTrace返回的异常捕获的堆栈帧。 (这就是像log4j这样的记录器框架在幕后做的事情......)

另见:Accessing caller information quickly 2

1 - 没有具体的“获取我的来电者的名字”方法。此外,我描述的方法实际上是非可移植的,因为它允许Throwable::getStackTrace返回一个空的数组帧。

2 - 最重要的答案提到了一些非便携式替代方案。使用StackWalker API的Java 9版本很有前景,但它仍然相对昂贵,因为StackWalker需要对堆栈帧进行快照。