0

我正在研究一些 JPA 的东西,我对你必须编写的一些启动代码有点困惑。

EntityManagerFactory factory = Persistence.createEntityManagerFactory("sample");
EntityManager manager = factory.createEntityManager();
EntityTransaction transaction = manager.getTransaction();

这三个变量都有一个接口作为它们的类型。我们怎么能做这样的事情

manager.persist()
transaction.commit()

等如果接口不能被实例化?

4

4 回答 4

2

接口不能被实例化,但接口引用可以包含实现该接口的任何类的对象。所以在你的情况下

EntityManagerFactory factory 

是一个接口的引用,它持有实现它的类的对象,由以下方式返回:

Persistence.createEntityManagerFactory("sample");

因此这个陈述变得正确:

EntityManagerFactory factory = Persistence.createEntityManagerFactory("sample");
于 2013-07-17T17:49:00.907 回答
1

你是对的。接口不能被实例化,但它们提供了一个契约来调用实现接口的对象上的方法。

因此,例如,当您查看EntityManager,factory.createEntityManager()正在返回一个实现接口的对象EntityManager。接口确保返回的对象提供某些必需的方法。

于 2013-07-17T17:50:25.343 回答
0

我想你误解了这里发生的事情。

  EntityManager manager = factory.createEntityManager(); // here manager is only a reference You are getting that from EntityManagerFactory. 

现在 Factory 类返回管理器类型对象。Java中没有接口的实例化

于 2013-07-17T17:55:52.100 回答
0

我认为这比解释更好。

例子:

public class AttackCommand implements Command {}...
public class DefendCommand implements Command {}...
....

假设我们想将这些添加到一个通用的命令列表中。然后你可以将这些添加到下面的列表中。

(在新班级)

public ArrayList<Command> commands = new ArrayList();

public CommandManager() {
    commands.add(new AttackCommand());
    commands.add(new DefendCommand());
}

现在这就是假设引用的来源。如果我们想按名称获取命令列表(假装命令有一个 getName 方法),或者通过 AttackCommand 获得最后一个被攻击的目标(假装它有一个 LastAttacked 方法)怎么办?

public void printNames() {
    for (Command cmd : commands) {
        System.out.println(cmd.getName());
    }
}

public Entity getLastAttackTarget() {
    for (Command cmd : commands) {
        if (cmd instanceof AttackCommand) {
            return cmd.lastAttacked();
        }
    }
}

(我知道只按名称抓取的命令映射会更好,但为了示例......)

本质上,它是对继承接口的所有事物的更好的通用引用,而不是接口本身。

于 2013-07-17T17:58:40.423 回答