考虑这个程序:
public class test {
public static void main(String [] args){
Runnable r = new Runnable() {
public void run() {
System.out.print("foo");
}
};
Thread t = new Thread(r) {
public void run() {
System.out.print("bar");
}
};
t.start();
}
}
运行输出
bar
我想知道为什么会这样。
我的理解:
我们通过重写run方法实例化一个实现Runnable的匿名内部类。并将其分配给r。
接下来,我们将此runnable传递给Thread类构造函数。但是我们还创建了一个新的匿名内部类,它通过覆盖run来扩展Thread。
所以我们现在有两个跑步方法,第二个将优先于第一个。
我很困惑如果我错了请纠正我。
在现实世界的Java编程中也使用了这些疯狂的东西吗? (我的教授说是的,这就是让我们继续前进的原因:D)。
答案 0 :(得分:3)
虽然您将Runnable实例传递给构造函数,但您以这种方式重写了run方法,它不会使用r
。
答案 1 :(得分:2)
标准的Thread.run
方法会在您传入的run
上调用Runnable
。在您的情况下,您将覆盖Thread的行为并将其替换为{{1忽略给定run
。
不幸的是,这些疯狂的事情做在现实世界中发生。这就是为什么使用静态分析工具和单元测试来确保获得预期行为的好主意:)
答案 2 :(得分:1)
当您覆盖其run()方法时,您将覆盖线程的默认行为。通过这种方式,您可以控制顺序以及是否运行r
。
public void run() { // ignores "r"
System.out.print("bar");
}
或
public void run() {
super.run(); // runs "r" first.
System.out.print("bar");
}
或
public void run() {
System.out.print("bar");
super.run(); // runs "r" second.
}
或
public void run() {
super.run(); // runs "r" first.
System.out.print("bar");
super.run(); // and runs "r" second.
}
或
public void run() {
r.run(); // runs "r" first.
System.out.print("bar");
r.run(); // and runs "r" second.
}
答案 3 :(得分:0)
方法Thread.run()
通常查看线程是否使用runnable构造。在这种情况下,它会调用Runnable.run()
,否则不会执行任何操作。您通过覆盖Thread.run()
来更改此行为,因此永远不会调用您的runnable。