如果我创建一个新的Java类,如下所示:
class A
{
public void run() {
// do something
}
}
然后我这样做:
new Thread(new A()).start()
然后我希望它运行run()方法。但它没有。
为什么不能将任何具有run方法的对象作为参数传递给new Thread()?
为什么java不能允许任何带有run()方法的类运行?以这种方式让java实现线程会有问题吗?
因为这就是具有鸭子类型的语言(例如JavaScript)会做的事情。Java不是这样一种语言。具有相同方法的两个类是不相关的。重要的是它们类之间的继承关系。
由于Thread
构造函数接受Runnable
作为参数,因此只有实现了Runnable
接口的类的实例才能作为参数传递。
Java不使用结构类型
使A
类实现Runnable接口。
编译器需要保证类型安全,通过提供Runnable接口可以保证。
Thread
想要调用一个例程,在java中它被定义为run()
。唯一的方法是,如果知道传递的对象有run()
方法。此问题的面向对象方法是定义一个接口,该接口强制出现run()
方法。
简短的回答:因为Java不是那样工作的。
长话短说:线程有几个构造函数,其中一个将实现Runnable接口的类的实例作为参数。如果一个类没有实现这个接口,它就不能被使用。
接口是结构的保证。实现Runnable的类保证实现具有public void run()
签名的方法,该方法不会引发检查异常,也不会返回任何内容。如果没有接口,a)检查和b)强制
因为Thread
需要Runnable
实例(实现Runnable
的对象),而不是具有run()
方法的。
这个特性被称为duck typing,在Groovy中实现。
它看起来像相同的界面,当然,因为你有"run()"在其中。但Java不是这样工作的。线程需要一个实现Runnable接口的对象。这意味着Java编译器可以提前拼凑代码,因为它知道在哪里可以找到run()方法。从某种意义上说,接口指向它。当您实现该接口时,您正在"填充"线程构造函数已经设置为指向的槽。界面把东西编织在一起,把东西排列起来,这样所有的东西都匹配起来。可以定义一种计算机语言,允许您所要求的内容,但随后必须进行各种分析才能找到内容,然后进行进一步检查以检测何时违反合同——这将是非常低效且容易出错的。接口使得 Java编译器和 Java程序员更容易使用