如何利用Java接口来跟踪在计算文件Main.java中的表达式Main.reverseString ( args[0] )时可能进行的递归调用
以下是文件Main.java:
public class Main
{
public static void main ( String [] args )
{
System.out.println ( "args[0] ..... " + args[0] ) ;
String reversed = Main.reverseString ( args[0] ) ;
System.out.println ( "reversed .... " + reversed ) ;
} // main
public static String reverseString ( String s )
{
if ( s.length() <= 1 )
return s ;
return ( (new StringBuilder(reverseString(s.substring(1))))
.append(s.charAt(0)).toString() ) ;
} // reverseString
} // Main我的跟踪程序(RecursionTracer)如下所示:
import com.sun.jdi.* ;
import com.sun.jdi.connect.* ;
import com.sun.jdi.request.* ;
import com.sun.jdi.event.* ;
import java.util.* ;
public class RecursionTracer
{
public static void main ( String [] args ) throws Exception
{
LaunchingConnector launchingConnector
= Bootstrap.virtualMachineManager().defaultConnector() ;
Map<String, Connector.Argument> env
= launchingConnector.defaultArguments() ;
env.get("main").setValue ( Main.class.getName() ) ;
VirtualMachine vm = launchingConnector.launch(env) ;
ClassPrepareRequest classPrepareRequest
= vm.eventRequestManager().createClassPrepareRequest() ;
classPrepareRequest.addClassFilter ( Main.class.getName() ) ;
classPrepareRequest.enable() ;
EventSet eventSet = null ;
do
{
eventSet = vm.eventQueue().remove() ;
for ( Event event : eventSet )
{
if ( event instanceof ClassPrepareEvent )
{
MethodEntryRequest methodEntryRequest
= vm.eventRequestManager().createMethodEntryRequest() ;
methodEntryRequest.addClassFilter ( Main.class.getName() ) ;
methodEntryRequest.enable() ;
} // if ClassPrepareEvent
if ( event instanceof MethodEntryEvent )
{
System.out.println ( "\n--------------------------------------" ) ;
MethodEntryEvent methodEntryEvent = (MethodEntryEvent) event ;
com.sun.jdi.Method method = methodEntryEvent.method () ;
System.out.println ( "MethodEntryEvent has occurred ..." ) ;
System.out.println ( methodEntryEvent ) ;
System.out.println ( method ) ;
System.out.println ( "======================================\n" ) ;
} // if MethodEntryEvent
vm.resume() ;
} // for each event
}
while ( eventSet != null ) ;
} // main
} // RecursionTracer我编译了Main.java和RecursionTracer.java,如下所示:
del *.class
D:\Java\JDK-11~1.1\bin\javac.exe -g Main.java RecursionTracer.java -Xlint:unchecked当我运行RecursionTracer时,它的输出是:
D:\>D:\Java\JDK-11~1.1\bin\java.exe RecursionTracer
--------------------------------------
MethodEntryEvent has occurred ...
MethodEntryEvent@Main:5 in thread main
Main.main(java.lang.String[])
======================================
Exception in thread "main" com.sun.jdi.VMDisconnectedException
at jdk.jdi/com.sun.tools.jdi.EventQueueImpl.removeUnfiltered(EventQueueImpl.java:200)
at jdk.jdi/com.sun.tools.jdi.EventQueueImpl.remove(EventQueueImpl.java:97)
at jdk.jdi/com.sun.tools.jdi.EventQueueImpl.remove(EventQueueImpl.java:83)
at RecursionTracer.main(RecursionTracer.java:26)我原以为每次输入方法Main.reverseString时都会出现Main.reverseString,但是,从上面的输出可以看出,唯一的MethodEntryEvent是当执行进入Main.main时。为什么没有MethodEntryEvent为Main.reverseString显示?此外,如何才能显示这样的MethodEntryEvent?最后,在每次调用该方法时,最好能看到提供给Main.reverseString的参数。
发布于 2019-06-07 01:49:30
您看不到任何其他方法,因为您的代码没有进行任何方法调用,而是在主方法的第一行得到一个ArrayIndexOutOfBoundsException,因为您没有向main方法传递任何参数。
一个简单的解决方案是修改main方法,并将其添加为第一行:
args = new String[]{ "foobar"};这会给它带来一些逆转的东西。在使用LaunchingConnector启动JRE时,应该有一种传递参数的方法。
https://stackoverflow.com/questions/56485730
复制相似问题