我在 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 documentation,RowMapper是一个接口。它看起来像一个基于RowMapper接口的匿名类定义。 new
关键字有点混乱,让我想知道这是否也创建了一个匿名类的实例。我猜是的,因为如果类没有名称,你将如何在定义它的行之后创建一个实例?
任何人都可以证实我的猜测:
答案 0 :(得分:11)
这是一个基于RowMapper接口的匿名类定义
这正是它的本质。
它会创建该类的单个实例吗?
是的。那是对的。
答案 1 :(得分:4)
该代码以匿名方式实现接口。
语法类似于:
Runnable runnable = new Runnable() {
public void run() {
}
};
请注意声明末尾的分号。这里runnable对象虽然保存了对Runnable接口的引用,但实际上包含了已实现的对象。这是你的运行时多态性!
答案 2 :(得分:3)
你的猜测是完全正确的。匿名类定义可以基于非final类或接口,并且必须实现所有抽象(或接口)方法。声明匿名类的唯一可用语法是new
,它还具有实例化匿名类的一个实例的效果(在程序过程中,可以创建相同匿名类的许多实例,如果这段代码执行了好几次)。
答案 3 :(得分:2)
接口告诉构建的类实例应该具有哪些方法,或者是否是标签接口,然后是与之关联的行为类型。
匿名类是基本上在实例化类实例时也使用自定义代码扩展它的类。因此,如果您要实例化一个接口,那么您必须编写使用该接口描述的所有方法,并且只要您至少做了那么多,编译器就会很高兴。这是在这里完成的。
是。如您所见,mapRow()
函数已被编写。如果你调试你可以看到的代码,那不是一个接口实例的类,而是扩展接口的类。在抽象类或只是类的情况下,它将是相同的 - 扩展。因此,如果课程最终,则无法为其编写匿名课程。
嗯,它扩展了它并成为它的一个实例。它将是单个实例,并且对它的任何后续调用将导致不同的类。如果您调试代码,那么您甚至可以看到与其动态关联的不同类名。
答案 4 :(得分:0)
仅仅从上面的代码中不知道RowMapper,你可以假设,基于RowMapper(可能是一个接口或类)的新匿名类被实例化。
答案 5 :(得分:0)
声明匿名类,在下面的示例中,它创建了两个实例。
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();
}
}