1

我需要编写一个使用递归的类可以扩展的父 Java 类。每当调用堆栈发生变化时(你进入一个方法,暂时离开它去另一个方法调用,或者你已经完成了方法),父类将能够意识到然后打印出来。我希望它在控制台上打印,但每次也要清除控制台,以便它水平显示堆栈,这样您就可以看到每个堆栈的高度,以查看弹出的内容和弹出的内容......如果基线也打印出来达到递归函数。

第一的。如何使用 StackTraceElements 和 Thread 类自动检测堆栈何时弹出或推送元素而不手动调用它?

其次,我将如何进行清算?

例如,如果我有代码:

public class recursion(int i)
{ 
    private static void recursion(int i)
    {
        if(i < 10)
            System.out.println('A');
        else
        {
            recursion(i / 10 );
            System.out.println('B');
        }
    } 
    public static void main(String[] argv)
    {
        recursion(102);
    }

}

进入main()时需要打印栈,从main()进入recursion(102)时,从recursion(102)进入recursion(102 / 10),即recursion(10)时,进入recursion(10 / 10),即recursion(10)中的recursion(1)。当到达基线递归(1)时打印出一条消息。然后打印出函数递归(10),递归(102)和main()的反向重新访问堆栈。最后打印出我们正在退出 main()。

4

2 回答 2

2

Thread类允许管理操作系统线程,它与调用堆栈没有任何关系。StackTraceElement代表一个堆栈框架,但你需要一个StackTrace来获得它。

您正在寻找堆栈跟踪更改时的通知,例如添加(输入方法)或删除(退出方法)框架。

到目前为止,最适合这项任务的工具是AspectJ. 它允许您定义advices(一种方法)在输入或存在其他方法时被调用(除了其他情况)。这些导致通知被调用的触发器被调用pointcuts——它们可以是方法入口、出口,并且可以使用通配符来描述方法:切入点MyClass.get*适用于 MyClass 的所有 get 方法。

于 2012-12-08T20:45:57.843 回答
0

在看到你的答案之前,我开始写自己的。它的形式很简单,但外壳是:

包堆栈跟踪记录器;

import java.util.ArrayList;

public class StackTraceLogger 
{

static final int MAX_ROW = Integer.MAX_VALUE;
static final int MAX_COLUMN = Integer.MAX_VALUE;

static public ArrayList<ArrayList<String>> stringTrace;
//private ArrayList<ArrayList<StackTraceElement>> stack;


public StackTraceLogger()
{
     stringTrace = new ArrayList< ArrayList <String>>();
    //stack = new ArrayList<ArrayList<StackTraceElement>>();
}

static public void addStack(StackTraceElement[] inputTrace) 
{
        int size = inputTrace.length;
        // make an ArrayList with the strings of all the StrackTraceElements
        ArrayList<String> str = new  ArrayList<>(size);

        for(int i = 0; i < size; i++)
        {
            str.add(i,inputTrace[i].getMethodName());
        }   

        // Add the ArrayList to the 2D ArrayList of the stacks

}
static public void printTrace()
{

/*  if(stringTrace.get(0).size() > 0)
    {
        for(int i = 0; i < stringTrace.size(); i++)
        {
            System.out.println(stringTrace.get(i));
            for(int j = 0; j < stringTrace.get(j).size(); j++)
                System.out.println(stringTrace.get(i).get(j));
        }
    }*/
}

static private ArrayList<String> convertToArrayList(StackTraceElement[] inputTrace) 
{
    ArrayList<String> strTrace = new ArrayList<>();
    for(int j = 0; j < inputTrace.length; j++ )
        strTrace.add(inputTrace[j].getMethodName());
    return strTrace;
}
}
于 2012-12-12T20:10:58.940 回答