A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("Runnable-->run");
                    }
                }) {
                    @Override
                    public void run() {
                        System.out.println("Thread-->run");
                    }
                }.start();
先解释一下这个代码,可能有的同学已经忘了匿名内部类的使用和创建!
创建一个Thread的子类对象并重写Thread的run()方法,通过Thread的子类对象的构造方法传递一个Runnable接口的实现类对象并重写Runnable接口的run()方法!
输出结果是: Thread-->run
为什么执行的是Thread子类的run(),难道不应该是Runnable接口实现类对象的run()吗?
接下来看Thread的源码
public void run() {
        if (target != null) {
            target.run();
        }
    }

target哪来的呢,其实就是Thread的构造方法传递的Runnable接口的实现类对象,源码意思说如果传递的实现类对象不为空则调用实现类对象的run方法,那么为什么结果调用的却是Thread子类对象的run(),那是因为源码中有判断是否为空,不为空调用Runnable的run(),结果我们的代码是重写了Thread的run方法,所以执行的结果就是Thread的run方法!
接下来有个问题,如果是以下代码,执行的结果会是什么呢???
new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("Runnable-->run");
                    }
                }) {
                    @Override
                    public void run() {
                        super.run();
                        System.out.println("Thread-->run");
                    }
                }.start();

有了对第一个案例的理解,这个就比较好理解了!
重写Thread的run()方法,并在第一行调用了父类的run();父类的run()是执行了Thread()的构造中传递过来的Runnable接口的实现类对象的run方法,所以先执行Runnable的run(),然后执行System.out.println("Thread-->run");
结果就是:
Runnable-->run   
Thread-->run



42 个回复

倒序浏览

public class TestDemo {

        public static void main(String[] args) {
                TestRunnable tr = new TestRunnable();
                TestThread test = new TestThread(tr);
                test.start();
        }
}

class TestThread extends Thread {

        @Override
        public void run() {
                super.run();
                System.out.println("Thread-->run");
        }

        public TestThread(Runnable target) {
                super(target);
        }
}

class TestRunnable implements Runnable {

        @Override
        public void run() {
                System.out.println("Runnable-->run");
        }
}

完全体?
回复 使用道具 举报
虽然看不懂到但是觉得好厉害的样子啊
回复 使用道具 举报
虽然看不懂到但是觉得好厉害的样子啊
回复 使用道具 举报
居然还简单的说了一下源码,你们现在不建议看太深的源码,简单看看就行了,加油 你们是最棒的
回复 使用道具 举报
加油 你们是最棒的
回复 使用道具 举报
很不错 。
回复 使用道具 举报
一语惊醒梦中人, 贼酷!
回复 使用道具 举报
写的很好!简洁易懂
回复 使用道具 举报
说的很不错,不过看的我还是优点懵逼
回复 使用道具 举报
说实话,理解不了这位大神再说什么,有空再研究研究吧.
回复 使用道具 举报
详细又不啰嗦,直击重点!
回复 使用道具 举报
看了很久,第一个是我们重写的Thread run方法将源码中的覆盖了,第二个通过super调用没有被覆盖,这理解不知道对不对
回复 使用道具 举报
ycbin 初级黑马 2017-12-2 15:03:41
14#
看了好久终于看懂了,太难了,感觉自己的逻辑能力严重欠缺
回复 使用道具 举报
第一个看懂了 第二个的话看不太明白啊
回复 使用道具 举报
格式工整  思路清晰  如果加上注释就完美
回复 使用道具 举报
写的很好简单也能看的懂
回复 使用道具 举报
虽然看不懂,但是还是非常牛啊 向你学习
回复 使用道具 举报
写的很好!谢谢分享!
回复 使用道具 举报
翻了多少笔记,看了多少Demo,才看得懂这括号和换行,才明白佳哥的话:不复习真的会忘,而且会忘得很干净······
回复 使用道具 举报
123下一页
您需要登录后才可以回帖 登录 | 加入黑马