我需要找到一个方法的调用者。是否可以使用堆栈跟踪或反射?
当前回答
Oneliner:
Thread.currentThread().getStackTrace()[2].getMethodName()
注意,您可能需要将2替换为1。
其他回答
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace()
根据Javadocs的说法:
数组的最后一个元素表示堆栈的底部,这是序列中最近的方法调用。
一个stacktracement有getts()、getFileName()、getLineNumber()和getmethod。
您必须通过试验来确定需要哪个索引 (可能是stackTraceElements[1]或[2])。
下面是我根据本主题中显示的提示制作的部分代码。 希望能有所帮助。
(请随时提出任何建议来改进此代码,请告诉我)
柜台:
public class InstanceCount{
private static Map<Integer, CounterInstanceLog> instanceMap = new HashMap<Integer, CounterInstanceLog>();
private CounterInstanceLog counterInstanceLog;
public void count() {
counterInstanceLog= new counterInstanceLog();
if(counterInstanceLog.getIdHashCode() != 0){
try {
if (instanceMap .containsKey(counterInstanceLog.getIdHashCode())) {
counterInstanceLog= instanceMap .get(counterInstanceLog.getIdHashCode());
}
counterInstanceLog.incrementCounter();
instanceMap .put(counterInstanceLog.getIdHashCode(), counterInstanceLog);
}
(...)
}
对象是:
public class CounterInstanceLog{
private int idHashCode;
private StackTraceElement[] arrayStackTraceElements;
private int instanceCount;
private String callerClassName;
private StackTraceElement getProjectClasses(int depth) {
if(depth< 10){
getCallerClassName(sun.reflect.Reflection.getCallerClass(depth).getName());
if(getCallerClassName().startsWith("com.yourproject.model")){
setStackTraceElements(Thread.currentThread().getStackTrace());
setIdHashCode();
return arrayStackTraceElements[depth];
}
//+2 because one new item are added to the stackflow
return getProjectClasses(profundidade+2);
}else{
return null;
}
}
private void setIdHashCode() {
if(getNomeClasse() != null){
this.idHashCode = (getCallerClassName()).hashCode();
}
}
public void incrementaContador() {
this.instanceCount++;
}
//getters and setters
(...)
}
Oneliner:
Thread.currentThread().getStackTrace()[2].getMethodName()
注意,您可能需要将2替换为1。
private void parseExceptionContents(
final Exception exception,
final OutputStream out)
{
final StackTraceElement[] stackTrace = exception.getStackTrace();
int index = 0;
for (StackTraceElement element : stackTrace)
{
final String exceptionMsg =
"Exception thrown from " + element.getMethodName()
+ " in class " + element.getClassName() + " [on line number "
+ element.getLineNumber() + " of file " + element.getFileName() + "]";
try
{
out.write((headerLine + newLine).getBytes());
out.write((headerTitlePortion + index++ + newLine).getBytes() );
out.write((headerLine + newLine).getBytes());
out.write((exceptionMsg + newLine + newLine).getBytes());
out.write(
("Exception.toString: " + element.toString() + newLine).getBytes());
}
catch (IOException ioEx)
{
System.err.println(
"IOException encountered while trying to write "
+ "StackTraceElement data to provided OutputStream.\n"
+ ioEx.getMessage() );
}
}
}
/**
* Get the method name for a depth in call stack. <br />
* Utility function
* @param depth depth in the call stack (0 means current method, 1 means call method, ...)
* @return method name
*/
public static String getMethodName(final int depth)
{
final StackTraceElement[] ste = new Throwable().getStackTrace();
//System. out.println(ste[ste.length-depth].getClassName()+"#"+ste[ste.length-depth].getMethodName());
return ste[ste.length - depth].getMethodName();
}
例如,如果你试图获得用于调试目的的调用方法行,你需要通过编写这些静态方法的Utility类: (旧的java1.4代码,只是为了说明StackTraceElement的潜在用法)
/**
* Returns the first "[class#method(line)]: " of the first class not equal to "StackTraceUtils". <br />
* From the Stack Trace.
* @return "[class#method(line)]: " (never empty, first class past StackTraceUtils)
*/
public static String getClassMethodLine()
{
return getClassMethodLine(null);
}
/**
* Returns the first "[class#method(line)]: " of the first class not equal to "StackTraceUtils" and aclass. <br />
* Allows to get past a certain class.
* @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils.
* @return "[class#method(line)]: " (never empty, because if aclass is not found, returns first class past StackTraceUtils)
*/
public static String getClassMethodLine(final Class aclass)
{
final StackTraceElement st = getCallingStackTraceElement(aclass);
final String amsg = "[" + st.getClassName() + "#" + st.getMethodName() + "(" + st.getLineNumber()
+")] <" + Thread.currentThread().getName() + ">: ";
return amsg;
}
/**
* Returns the first stack trace element of the first class not equal to "StackTraceUtils" or "LogUtils" and aClass. <br />
* Stored in array of the callstack. <br />
* Allows to get past a certain class.
* @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils.
* @return stackTraceElement (never null, because if aClass is not found, returns first class past StackTraceUtils)
* @throws AssertionFailedException if resulting statckTrace is null (RuntimeException)
*/
public static StackTraceElement getCallingStackTraceElement(final Class aclass)
{
final Throwable t = new Throwable();
final StackTraceElement[] ste = t.getStackTrace();
int index = 1;
final int limit = ste.length;
StackTraceElement st = ste[index];
String className = st.getClassName();
boolean aclassfound = false;
if(aclass == null)
{
aclassfound = true;
}
StackTraceElement resst = null;
while(index < limit)
{
if(shouldExamine(className, aclass) == true)
{
if(resst == null)
{
resst = st;
}
if(aclassfound == true)
{
final StackTraceElement ast = onClassfound(aclass, className, st);
if(ast != null)
{
resst = ast;
break;
}
}
else
{
if(aclass != null && aclass.getName().equals(className) == true)
{
aclassfound = true;
}
}
}
index = index + 1;
st = ste[index];
className = st.getClassName();
}
if(resst == null)
{
//Assert.isNotNull(resst, "stack trace should null"); //NO OTHERWISE circular dependencies
throw new AssertionFailedException(StackTraceUtils.getClassMethodLine() + " null argument:" + "stack trace should null"); //$NON-NLS-1$
}
return resst;
}
static private boolean shouldExamine(String className, Class aclass)
{
final boolean res = StackTraceUtils.class.getName().equals(className) == false && (className.endsWith("LogUtils"
) == false || (aclass !=null && aclass.getName().endsWith("LogUtils")));
return res;
}
static private StackTraceElement onClassfound(Class aclass, String className, StackTraceElement st)
{
StackTraceElement resst = null;
if(aclass != null && aclass.getName().equals(className) == false)
{
resst = st;
}
if(aclass == null)
{
resst = st;
}
return resst;
}
推荐文章
- 在Android上将字符串转换为整数
- 为什么“System.out。”println“工作在Android?
- 在Java中什么时候使用可变参数?
- Mockito的argumentCaptor的例子
- 我如何告诉Spring Boot哪个主类用于可执行jar?
- 如何将Java8流的元素添加到现有的列表中
- 在Java 8中是否可以转换流?
- 不区分大小写的字符串作为HashMap键
- 什么是maven中的“pom”打包?
- 在Java中创建一个自定义事件
- 创建正则表达式匹配数组
- 我如何在Java中初始化一个全零的数组列表?
- 主体、使用者和主体之间的意义和区别是什么?
- 将字节转换为十六进制
- HashSet和HashMap的区别?