基于接口的匿名类定义……也许?

我在Spring in Action一书中看到了这个Java片段,但我对语言结构并不熟悉。

new RowMapper() { public Object mapRow() throws SQLException, DataAccessException { Motorist motorist = new Motorist(); motorist.setId(rs.getInt(1)); motorist.setEmail(rs.getString(2)); motorist.setPassword(rs.getString(3)); motorist.setFirstName(rs.getString(4)); motorist.setLastName(rs.getString(5)); return motorist; } } 

根据Spring文档 ,RowMapper是一个接口。 它看起来像一个基于RowMapper接口的匿名类定义。 new关键字有点令人困惑,让我想知道这是否也会创建一个匿名类的实例。 我猜是的,因为如果类没有名称,你将如何定义它的行之后创建一个实例?

任何人都可以证实我的猜测:

  • 这是一个基于RowMapper接口的匿名类定义,和
  • 它创建了该类的单个实例?

这是一个基于RowMapper接口的匿名类定义

这正是它的本质。

它创建了该类的单个实例?

是的。 那是对的。

该代码以匿名方式实现接口。

语法类似于:

 Runnable runnable = new Runnable() { public void run() { } }; 

请注意声明末尾的分号。 这里runnable对象虽然保存了对Runnable接口的引用,但实际上包含了已实现的对象。 这是你的运行时多态性!

你的猜测是完全正确的。 匿名类定义可以基于非final类或接口,您必须实现所有抽象(或接口)方法。 声明匿名类的唯一可用语法是new ,它还具有实例化匿名类的一个实例的效果(在程序过程中,如果此代码是,则可以创建相同匿名类的许多实例)执行了好几次)。

接口告诉构建的类实例应该具有哪些方法,或者你的标签接口是什么,然后与它相关联的行为类型。

匿名类是基本上在实例化类实例时也使用自定义代码扩展它的类。 因此,如果您要实例化一个接口,那么您必须编写使用该接口描述的所有方法,并且只要您至少做了那么多,编译器就会很高兴。 这是在这里完成的。

这是一个基于RowMapper接口的匿名类定义吗?

是。 正如您所看到的,已经编写了mapRow()函数。 如果你调试你可以看到的代码,那不是一个接口实例的类,而是扩展接口的类。 在抽象类或只是类的情况下,它将是相同的 – 扩展。 因此,如果课程是最终的,你就不能为它写匿名课程。

它是否创建了该类的单个实例?

好吧,它扩展了它并成为它的一个实例。 它将是单个实例,并且对它的任何后续调用将导致不同的类。 如果您调试代码,那么您甚至可以看到与其动态关联的不同类名。

仅仅从上面的代码中不知道RowMapper,你可以假设所有基于RowMapper的新匿名类(可能是一个接口或类)都是实例化的。

声明匿名类,在下面的示例中,它创建了两个实例。

 public class Multithread { void test(){ new Runnable() { @Override public void run() { System.out.println("1"); } }.run(); new Runnable() { @Override public void run() { System.out.println("11"); } }.run();} public static void main(String[] args) { new Multithread().test(); } }