我有以下代码,其目标是当一个方法在父级上调用时,它会在它的所有子级上调用相同的方法,这就是实际工作完成的地方。
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/