我正在研究一些JPA的东西,我对你必须编写的一些启动代码感到困惑。
EntityManagerFactory factory = Persistence.createEntityManagerFactory("sample");
EntityManager manager = factory.createEntityManager();
EntityTransaction transaction = manager.getTransaction();
这三个变量都有一个接口作为它们的类型。我们怎样才能做到像
这样的事情manager.persist()
transaction.commit()
等,如果接口无法实例化?
答案 0 :(得分:2)
接口无法实例化,但接口引用可以保存实现该接口的任何类的对象。所以在你的情况下
EntityManagerFactory factory
是接口的引用,它持有实现它的类的对象,返回:
Persistence.createEntityManagerFactory("sample");
因此这句话变得正确:
EntityManagerFactory factory = Persistence.createEntityManagerFactory("sample");
答案 1 :(得分:1)
你是对的。接口无法实例化,但它们提供了在实现接口的对象上调用方法的契约。
因此,当您查看EntityManager
时,factory.createEntityManager()
将返回实现接口EntityManager
的对象。接口确保返回的对象提供某些必需的方法。
答案 2 :(得分:0)
我认为你误解了这里发生的事情。
EntityManager manager = factory.createEntityManager(); // here manager is only a reference You are getting that from EntityManagerFactory.
现在Factory类返回管理器类型对象。 Java中没有实例化接口
答案 3 :(得分: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();
}
}
}
(我知道按名称抓取命令的地图会更好,但为了示例......)
从本质上讲,它是对继承接口的所有事物的更好的一般引用,而不是接口本身。