我有以下代码,其目标是当在父项上调用方法时,它会在所有子项上调用相同的方法,这就是实际工作完成的地方。
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
}
}
答案 0 :(得分:2)
您的解决方案(sneakyHiddenWork
)是最佳解决方案......尽管您选择的名称缺少重点。 (这不是“鬼鬼祟祟”。做这种事情是一种常见的模式。)
是的,可以找出调用方法的名称是什么,但在Java 1 中没有很好地支持,并且该过程昂贵 。您实例化一个异常对象,然后查看由Throwable::getStackTrace
返回的异常捕获的堆栈帧。 (这就是像log4j这样的记录器框架在幕后做的事情......)
另见:Accessing caller information quickly 2
1 - 没有具体的“获取我的来电者的名字”方法。此外,我描述的方法实际上是非可移植的,因为它允许Throwable::getStackTrace
返回一个空的数组帧。
2 - 最重要的答案提到了一些非便携式替代方案。使用StackWalker
API的Java 9版本很有前景,但它仍然相对昂贵,因为StackWalker
需要对堆栈帧进行快照。