在JDBC中使用ResultSet时,真正得到的是什么?

在JDBC中使用ResultSet时,真正得到的是什么?,jdbc,interface,Jdbc,Interface,下面的伪代码可以工作,这对于任何从事过JDBC工作的人来说可能都不奇怪: ResultSet rs = foo.executeQuery(); boolean hasNext = rs.next(); while(hasNext) { bar(); boolean hasNext = rs.next(); } ResultSet()是一个接口,所以next()应该没有实现,只有一个方法声明。那么代码是如何成功运行的呢?我在网上找到的最佳答案是,返回的是实现ResultSet接口

下面的伪代码可以工作,这对于任何从事过JDBC工作的人来说可能都不奇怪:

ResultSet rs = foo.executeQuery();
boolean hasNext = rs.next();
while(hasNext) {
    bar();
    boolean hasNext = rs.next();
}
ResultSet()是一个接口,所以next()应该没有实现,只有一个方法声明。那么代码是如何成功运行的呢?我在网上找到的最佳答案是,返回的是实现ResultSet接口的类的实例


这个答案对我来说很有意义(它证实了我在实际查找它之前的假设),但它只会引出另一个问题:你怎么知道你会回到什么样的课堂?从理论上讲,它不能以一种意外或不希望的方式重写接口的方法吗?

在运行时,JVM知道返回的是什么类型的类。您甚至可以使用javainstanceof关键字自己访问它

很有可能您得到了以不希望的方式重写此方法的内容。但是方法的签名总是相同的,并且只有在运行时才会出现类转换问题。这就是像Java这样的OOP语言的全部继承点


更多信息。

在运行时,JVM知道返回什么类型的类。您甚至可以使用javainstanceof关键字自己访问它

很有可能您得到了以不希望的方式重写此方法的内容。但是方法的签名总是相同的,并且只有在运行时才会出现类转换问题。这就是像Java这样的OOP语言的全部继承点


更多信息。

您得到的是一个实现这些接口的类,它可以在数据库驱动程序中找到

例如,如果您连接到MySQL,您可能会使用来自的驱动程序


驱动程序实现这些接口。如果从数据库提供程序获取接口,它不会以意外或不希望的方式实现接口(当然,供应商之间存在实现差异,但这不应该是什么大问题;例如,我今天在使用
DatabaseMetaData.getSQLStateType()时被烧坏了)
。这应该返回1或2,但我的驱动程序实现决定返回0,但其他方面我都没有问题)。

您得到的是一个实现这些接口的类,它可以在数据库驱动程序中找到

例如,如果您连接到MySQL,您可能会使用来自的驱动程序


驱动程序实现这些接口。如果从数据库提供程序获取接口,它不会以意外或不希望的方式实现接口(当然,供应商之间存在实现差异,但这不应该是什么大问题;例如,我今天在使用
DatabaseMetaData.getSQLStateType()时被烧坏了)
。这应该返回1或2,但我的驱动程序实现决定返回0,但其他方面我都没有问题。)

顺便说一句,这与您的问题无关,但我相信推荐的结果集用法应该是:

ResultSet rs = conn.executeQuery();
while (rs.next()) {
   bar();
}
这将导致代码更简洁/更短,而不必使用临时布尔变量


更相关的一点是,如果您使用“品牌”实现者(在本例中为Oracle、MySQL、Microsoft等),由于冗长的文档、大型用户社区等原因,您通常可以相信接口能够正确实现。就像在杂货店一样,只有当你能确认内部发生的情况与你期望的品牌名称相同时,才使用通用产品。

顺便说一句,这与你的问题无关,但我相信推荐使用的结果集应该是这样的:

ResultSet rs = conn.executeQuery();
while (rs.next()) {
   bar();
}
这将导致代码更简洁/更短,而不必使用临时布尔变量


更相关的一点是,如果您使用“品牌”实现者(在本例中为Oracle、MySQL、Microsoft等),由于冗长的文档、大型用户社区等原因,您通常可以相信接口能够正确实现。就像在杂货店一样,只有当您能够确认内部发生的情况与您期望的品牌名称相同时,才能使用通用产品。

谢谢。当然,你是对的。这是一个如此古老的问题,我不记得我问的原因,但我打赌我生成了一些调试代码。当我调试时,我倾向于故意把东西分开太多,这样我可以更精确地完成。谢谢。当然,你是对的。这是一个如此古老的问题,我不记得我问的原因,但我打赌我生成了一些调试代码。在调试时,我倾向于故意过多地将事物分割开来,以便更精确地执行-->打印实现类。如果JDBC驱动程序是开源的,请看一看。@BalusC,+1是一个很好的通用技巧,尽管我早就忘记了我最初问这个问题的原因。我打赌这只是初学者对接口和多态性的使用感到困惑,没有意识到它是返回的实例,实际上包含了具体的实现。接口只是定义了可以在具体实现中使用的方法。JDBC这种特殊情况的优点是,您可以轻松切换DB和/或JDBC驱动程序,而不会影响JDBC代码(当然,除了DB供应商特定的SQL语句/子句/函数之外)。
System.out.println(rs.getClass())-->打印实现类。如果JDBC驱动程序是开源的,请看一看。@BalusC,+1是一个很好的通用技巧,尽管我早就忘记了我最初问这个问题的原因。我打赌这只是初学者对接口和多态性的使用感到困惑,没有意识到它是返回的实例,实际上包含了具体的实现。界面只是定义了冰毒