2016-09-29 63 views
9

我提供了一个API,并且需要知道API调用的方法。我可以使用反射或线程堆栈跟踪,但这会包含很多运行时成本。如何确定方法的调用

我不需要确切的类名,每次调用的唯一引用就足够了。在C中,我通常会使用预处理器自动将__FILE____LINE__添加到方法调用中。

是否有Java(除了代码生成)方法以低运行时成本获得唯一的主叫方身份?

+2

可能的重复http://stackoverflow.com/questions/26425049/how-to-get-a-unique-method-identifier –

+2

只是想知道:你打算在这里解决什么问题? – GhostCat

+2

可能会看看AspectJ并在调用API时设置连接点? –

回答

3

一个解决办法是有它在传递一个缓存的Throwable

class StackPoint { 
    Throwable stack; 
    public Throwable getStack() { 
     if (stack == null) 
      stack = new Throwable(); 
     return stack; 
    } 
} 

public void methodToCall(StackPoint sp) { 
    Throwable t = sp.getStack(); 

} 


static final StackPoint one = new StackPoint(); 

methodToCall(one); // Have to remember to give each line a different StackPoint. 

注意:如果调用该主叫变化的方法,只录制过的第一个。


没有一个标准的模式,它是可能的,如果你想这是有效的调用者将需要通过唯一的ID。你可以做的最接近的用途是lambda。

public void methodToCall(Runnable run) { 
    Class id = run.getClass(); 

} 

你可以这样调用

methodtoCall(()->{}); 

这将创建一个不同的类的每次调用它的地方,即使多次出现在同一行。它不会创建垃圾,因为它每次都重复使用同一个对象。你可以把这个短与

void methodToCall(IntFunction fun) { 

} 

,并呼吁

methodToCall(a->1); 
+0

虽然我无法禁止呼叫站点两次传递相同的参数,但这是一个非常好的解决方案。如果传递的参数未知,我将使用堆栈跟踪来获取确切的调用站点,否则使用缓存的信息。 – ooxi

+1

但指望拉姆达的身份是错误的,不是吗? –

+1

@ooxi给予来电代码,他们可以复制和粘贴,而无需手动更改,意味着他们不太可能混淆它。 –

1

因为有所asynchroneous参与,分裂召集,并让API返回的ID。

Ticket callTicket = api.call(params); 
Logger.getLogger(getClass().getName(), Level.FINE, callTicket); 
Result result = callTicket.get(); 

上面有结果返回(同步)可能不是你的代码的情况。您的代码将在其他地方获得结果。但那也可能是一个票务系统。

+0

但是,如何确定是否应该在未检查堆栈跟踪的情况下返回新的故障单? – ooxi

+1

同一班级和同一线路上的每个呼叫都会从API中抽取一张新票。记录实例。在异步例外情况下,该票据是已知的,并且可以在日志中进行搜索。当然是不同的方法和观点。 –

+0

我当然更喜欢你的解决方案,因为它不切断客户端的代码和技术细节。尽管如此,我仍将@PeterLawrey的答案作为已接受的答案,因为它确实更直接地解决了问题。 – ooxi

相关问题