由runnable构造的线程对象会覆盖run方法

Jav*_*yer 5 java scjp

鉴于此示例代码:

Runnable r = new Runnable() {
  public void run() {
    System.out.print("Cat");
  }
};
Thread t = new Thread(r) {
  public void run() {
    System.out.print("Dog");
  }
};
t.start();
Run Code Online (Sandbox Code Playgroud)

为什么输出狗而不是猫?

Jon*_*eet 7

的实现runThread简单地调用Runnable构造函数提供的,如果有一个.你覆盖了那个代码,所以如果新线程只是run调用了它的方法,那么Runnable就会被忽略.当然,您应该能够查看源代码来检查...(我刚刚这样做了,虽然我不打算在这里发布源代码,但它完全按照我的描述进行.)

你真正暴露的是封装问题 - Thread 不应该有这些不同的,可能相互矛盾的方式来说明线程应该做什么.基本上,你几乎应该Thread直接扩展.仅仅因为它设计得很糟糕并不意味着你必须滥用那种糟糕的设计;)

编辑:这实际上是以一种稍微迂回的方式记录的.start()记录为:

导致此线程开始执行; Java虚拟机调用此线程的run方法.

run()记录为:

如果使用单独的Runnable运行对象构造此线程,则调用该Runnable对象的run方法; 否则,此方法不执行任何操作并返回.

因此,该run()方法被称为per start(),但是你已经重写了run(),这是唯一可以调用Runnable构造函数中提供的方法.

请注意,如果您重写了这样的方法:

Thread t = new Thread(r) {
  public void run() {
    super.run();
    System.out.print("Dog");
  }
};
Run Code Online (Sandbox Code Playgroud)

然后输出将是"CatDog".

  • @Cratylus:为什么不可能呢?其中哪些任务需要您*扩展*`线程`,而不仅仅是创建实例和设置属性?子类化应该与更改*行为*有关,而不仅仅是设置值。 (2认同)