面试题如图
判断该代码执行后,的输出为?
经过分析,Thread的匿名子类,自己拥有run方法,因此调用start方法会执行自己的run方法,执行结果如下:
但是,在我们把Thread中的run方法注掉之后,发现控制台返回的输出是Runnable的匿名子类的run方法输出,如图:
因为考虑虽然Thread类是实现了Runnable接口,考虑是,继承中的子类如果有需要调用的方法就不回去父类找,如果没有的话会先去父类找,如果父类没有需要执行的方法则会报错的原因造成。
但是,Thread匿名子类的一参构造器中,传入的的Runnable匿名子类两者应该并无继承关系,于是去Thread类的源码中,发现Thread类中的一参构造器调用了init()方法,并且将Runnable target(传入的Runnable实现子类)以形参的方式传入到inti方法中。
在Thread类中的init()方法中,我们发现它通过
this.target=target;
的方式将形参中传入的Runnable实现子类对象保存。
并且在Thread类中覆写父类的run()方法中,先对target判空,然后调用了target中的run()方法。
这到面试题所涉及到的难点,代码执行的是Thread匿名子类的run()方法,不执行传入Thread匿名子类的一参构造器中Runnable的匿名子类的run()是涉及到继承的知识,前面已提及;而后来扩展发现的是Thread一参构造器会接收传入的Runnable的实现子类,并在覆写的run()方法中调用Runnable实现子类的run方法。