Java 如何理解这个详细的多线程和匿名类相关代码?

Java 如何理解这个详细的多线程和匿名类相关代码?,java,Java,简单地说,我得到了这个世界。为什么可以这样写呢?第一个run方法是什么?这段精心设计的代码将匿名可运行类的实例传递给匿名线程类的实例,匿名线程类重写其通常的run实现 如果您重构它,它会变得更加清晰: public static void main(String[] args) { new Thread(new Runnable() { public void run() { System.out.println("hello");

简单地说,我得到了这个世界。为什么可以这样写呢?第一个run方法是什么?

这段精心设计的代码将匿名可运行类的实例传递给匿名线程类的实例,匿名线程类重写其通常的run实现

如果您重构它,它会变得更加清晰:

public static void main(String[] args) {

    new Thread(new Runnable() {
        public void run() {
            System.out.println("hello");
        }
    }) 
    {
        public void run() {
            System.out.println("world");
        }
    }.start();
}

传递给线程的Runnable(将由线程的start方法执行)被忽略,因为Thread对象也是匿名类的实例,其run方法具有自定义实现,这是硬编码的打印世界。

此代码创建线程的匿名子类的实例,然后启动该线程

该子类使用打印世界的方法重写线程的run方法


第一个run方法是Runnable接口匿名实现的一部分,该接口被传递给线程实例的构造函数。该实现将被忽略,因为线程实现会覆盖运行

传递给线程构造函数的可运行实例仅在线程启动时执行,如果线程的运行方法未被重写。

您已将打印hello的运行方法重写为打印world的运行方法。发生这种情况的原因是,在代码中,您使用一个匿名类扩展了Thread类,该类重写了run方法,因此永远不会调用Runnable参数的run。您可以更新代码以使用super.run从原始类调用runnable方法

以下是您的代码及其更改:

// The runnable instance
Runnable runnable = new Runnable() {
    public void run() {
        System.out.println("hello");
    }
};

// Anonymous Thread class with a custom run() method
new Thread(runnable) {
    public void run() {
        System.out.println("world");
    }
}.start();
Thread类以以下方式定义运行:

    new Thread(new Runnable() {
        public void run() {
            System.out.println("hello");
        }
    }) {
        public void run() {
            super.run();
            System.out.println("world");
        }
    }.start();
如果thread的Runnable实例目标字段不为null,它将调用该字段的run方法

因此,当您创建以这种方式重写此方法的匿名线程类时:

@Override
public void run() {
    if (target != null) {
        target.run();
    }
}
匿名实例的线程运行方法不再依赖目标字段来运行可运行实例。 它只执行以下代码:

new Thread(...) {
    @Override
    public void run() {
        System.out.println("world");
    }
}
因此,传递给线程构造函数的可运行实例被run完全忽略:


第一个run方法是Runnable接口的匿名实现的一部分,该接口是。。是否引用匿名实现?我认为匿名实现是由实现Runnable接口的匿名类创建的实例。是吗?给出一个等效的重构代码是我在这里的期望。谢谢还有一点不清楚:Runnable Runnable=newrunnable{}。我知道实例化一个实例就像ClassA ClassA=new ClassA一样,但是ClassA是一个类,而Runnable是一个接口。如何通过接口创建对象?我错在哪里?没有关键字扩展,所以这是一种特殊的继承方式吗?是的,这是一种特殊的继承形式,因为您创建了一个匿名类。有关更多信息,请参阅此链接
System.out.println("world");
new Runnable() {
    public void run() {
        System.out.println("hello");
    }
}