java - 有没有一种好方法可以知道一个方法是被 parent 还是从其他地方调用的?

标签 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 类的调用的好方法?因此,如果 doWork() 是从这个类链之外的子项上调用的,那么子项将调用 Log 方法,但是如果 doWork()在父级上调用只有父级会调用 Log 方法而子级不会?


我能想到的就是有这样的东西:

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
    }
}

最佳答案

您的解决方案 (sneakyHiddenWork) 是最好的解决方案……尽管您选择的名称没有捕获重点。 (这不是“鬼鬼祟祟”,做这种事情是一种常见的模式。)

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

另请参阅:Accessing caller information quickly 2


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

2 - 最佳答案暗示了几个不可移植的替代方案。使用 StackWalker API 的 Java 9 版本很有前途,但它仍然会相对昂贵,因为 StackWalker 需要对堆栈帧进行快照。

关于java - 有没有一种好方法可以知道一个方法是被 parent 还是从其他地方调用的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47744887/

相关文章:

java - Eclipse 声称来源不明,我不知道为什么

java - 为什么 getClass().getProtectionDomain().getCodeSource().getLocation().getPath() 在编译后的最终产品中不起作用?

c++ - 子类的构造函数后跟冒号后的基类构造函数是什么意思?

java - 如何从文本文件中读取我的输出?

java - 访问父类(super class)中的 protected 变量

c++ - 使用简单指针链接函数

javascript - 用 JavaScript 深度继承?

c# - C#继承和链接问题

c# - 按钮之间的继承 C# - windows 窗体

java - 我们可以删除 BigDecimal 中小数点前的 float 零吗