我们如何创建一个带有 Spring 的接口对象来自动装配它,但是在 java 中创建相同的对象是错误的?

How can we create an object of interface with Spring to autowire it but it's wrong to create the same object in java?

假设我们有一个界面为“ABC.java”

interface ABC {
    public void hello();
}

现在我们有一个 class 像“ABCimpl.java”

public class ABCimpl implements ABC{
    
    @Override
    public void hello(){
         System.out.println("Hello World!");
    }
}

现在我们还有一个 class 名为“DEFinpl.java”

public class DEFimpl{
    @Autowired
    ABC abc;

    public void trial(){
        abc.hello();
    }
}

但如果我们只是简单地使用 java,我们不会为接口创建对象。这是为什么? 这里发生了什么?

我们无法在 Java 中创建接口对象。

Interfaces in java 可以定义为完整的摘要 class with fields (public、static & final) 和空方法(public 和抽象)。虽然从 Java 8 开始我们可以定义默认方法,它可以有自己的主体,在 Java 9 中我们甚至可以有私有方法。

但要点是,在接口中我们没有对象级别的字段,因为默认情况下它们都是静态的。因此,拥有构造函数

是不合逻辑或有意义的

这意味着 --> 没有创建对象。

当我们使用 spring @Autowired 来初始化接口时,spring 并没有 实际上创建一个创建该接口的对象,而不是其子 class 的 对象。

在这种情况下,因为接口 ABC 仅存在一个子 class,即 class ABCImpl。

所以当我们使用@Autowired时Spring会做这样的事情:

ABC abc = new AbcImpl(); 

abc 只是一个引用变量,存储子class(接口ABC 实现之一)的对象。 如果我们有多个子 classes 并且我们使用 @Autowired,事情就会变得有趣。然后 spring 通过首先检查类型然后检查名称来解决这种歧义。如果两者相同,那么我们可以使用@Qualifier 之类的东西来添加一些额外的标签来区分它。