下面我们通过源码分析来阐述个中原理。在通过上一节分析的处理好命令行参数之后,monkeyrunner入口main函数的下一步就是去尝试根据这些参数来调用MonkeyRunnerStarter的构造函数:

178   public static void main(String[] args) {

179     MonkeyRunnerOptions options =

MonkeyRunnerOptions.processOptions(args);

180

181     if (options == null) {

182       return;

183     }

184

185

186     replaceAllLogFormatters(MonkeyFormatter.DEFAULT_INSTANCE,

options.getLogLevel());

187

188     MonkeyRunnerStarter runner =

new MonkeyRunnerStarter(options);

189     int error = runner.run();

190

191

192     System.exit(error);

193   }

194 }

代码8-3-1 初始化MonkeyRunnerStarter

 

其中的options参数就是上一节最后根据所有参数创建的MonkeyRunnerOptions对象,里面保存了所有的参数。往下我们进入MonkeyRunnerStarter的构造函数:

代码8-3-2 MonkeyRunnerStarter构造函数

 

55   public MonkeyRunnerStarter(MonkeyRunnerOptions options)

 56   {

 57     Map<String, String> chimp_options = new TreeMap();

 58     chimp_options.put("backend", options.getBackendName());

 59     this.options = options;

 60     this.chimp = ChimpChat.getInstance(chimp_options);

 61     MonkeyRunner.setChimpChat(this.chimp);

 62   }

仅从这个方法的几行代码我们可以看到它其实做的事情就是去根据‘backend’来初始化ChimpChat 并把该实例保存到MonkeyRunnerStarter的chimp成员变量中,同时也会调用MonkeyRunner的静态方法setChimpChat把该ChimpChat对象设置到MonkeyRunner的静态成员变量里面,为什么说它一定是静态成员变量呢?因为第61行保存该实例调用的是MonkeyRunner这个类的方法,而不是一个实例,所以该方法肯定就是静态的,而一个静态方法里面的成员函数也必然是静态的。大家跳进去MonkeyRunner这个类就可以看到:

51 static void setChimpChat(ChimpChat chimp)
52 {
53 chimpchat = chimp;
54 }

代码8-3-3 MonkeyRunner - setChimpChat