我无法理解下面的代码来创建Runnable
对象。有人可以清楚地解释一下这里发生了什么:
public class ThreadStart {
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<5;i++) {
System.out.println(i+" runnable thread...");
}
}
});
t1.start();
}
}
答案 0 :(得分:4)
此代码创建实现Runnable
接口的匿名类的实例(意味着它没有名称)。此实例将传递给Thread
类的构造函数。
答案 1 :(得分:4)
想象一下Runnable
的以下实现。一个实现接口的简单类。
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(i + " runnable thread...");
}
}
}
因此,为了按照您的预期方式创建Thread
,您必须提供Runnable
对象的实现。有多种方法可以实现这一目标。
最直接的方法可能是使用上面Runnable
的实例:
Thread t1 = new Thread(new MyRunnable());
另一种方法是直接在代码中提供Runnable
作为匿名内部类,您可以找到有关here的更多信息。
匿名内部类只是意味着您在代码中创建一个类作为表达式,您必须遵循相同的签名(即在这种情况下它实现Runnable
接口)。
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(i + " runnable thread...");
}
}
});
来自Oracle Docs:
匿名类表达式包含以下内容:
- 新操作员
- 要实现的接口的名称或要扩展的类。在此示例中,匿名类正在实现接口HelloWorld。
- 包含构造函数参数的圆括号,就像普通的类实例创建表达式一样。注意:实现接口时,没有构造函数,因此您使用一对空括号,如本例所示。
- 一个正文,它是一个类声明体。更具体地说,在正文中,方法声明是允许的,但语句不是。
所以,基本上你正在做的是将Runnable
传递给你的Thread
构造函数。如果您将它作为匿名类传递,您只需将其作为表达式传递给实际定义整个内部类的表达式。
此外,在Java 8中,您可以使用如下的lambda表达式替换匿名内部类:
Thread t3 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println(i + " runnable thread...");
}
});
答案 2 :(得分:1)
代码使用匿名类。您可以了解有关匿名类here的所有信息。
基本上,这意味着您将通过直接在方法调用中实现方法来创建实现Runnable
的类。
答案 3 :(得分:0)
您正在创建一个匿名内部类的实例,实现 Runnable
接口。如果您转到将放置.class
文件的目录,您可以看到使用名称ThreadStart$1.class
创建的匿名类。即,OuterClass$1.class
答案 4 :(得分:0)
使用实现Anonymous class
接口的Runnable
并传递给接受Runnable
类型
匿名类
匿名类使您可以使代码更简洁。它们使您能够同时声明和实例化一个类。他们就像当地的班级,除了他们没有名字。如果您只需要使用本地类一次,请使用它们。