【问题标题】:Does using a JDBC driver in a Java program work without reflection?在 Java 程序中使用 JDBC 驱动程序是否可以在没有反射的情况下工作?
【发布时间】:2018-07-12 21:48:29
【问题描述】:

当我们动态加载.class类文件时,需要使用反射来访问类中定义的方法,对吗?

当我们在 Java 程序中使用 JDBC 驱动程序时,

  • 如果我没记错的话,JDBC 驱动程序也是在后台动态加载的。
  • 但我们永远不需要使用反射来访问 JDBC 驱动程序中定义的方法。相反,我们import java.sql 并访问java.sql 中定义的类和方法。

在引擎盖下,是否有反思?如果没有,它如何在没有反射的情况下工作?

一般来说,当我们动态加载一个.java类文件时,我们如何消除或隐藏使用反射来访问类中定义的方法,就像JDBC驱动一样?

顺便问一下,JDBC 驱动程序是否准确定义了一个类?

谢谢。

【问题讨论】:

  • 仔细查看java.sql 包。几乎所有东西都是接口而不是类,所以任何实现接口的类都可以在幕后插入。
  • 仅供参考: 您不能“动态加载 .java 类文件”。您加载 .class 文件,而不是 .java 文件。
  • @Andreas 谢谢。已更正。

标签: java jdbc dynamic-loading


【解决方案1】:

JDBC驱动需要实现java.sql.Driver接口(例如oracle.jdbc.OracleDriver)。除此之外,JDBC 驱动程序代码只是普通的 Java 代码。它可以使用反射或任何其他 Java 语言功能。由驱动程序供应商决定是否值得,例如使用 Java 8 中引入的类将使其仅与 Java 8+ 兼容。

动态加载和非动态加载取决于 JVM 和 ClassLoader 的实现。某些技术(如 OSGI)通过实现允许卸载应用程序部分的 ClassLoader 来提供更大的灵活性。

加载 JDBC 驱动程序类应该很少发生,并且被 JVM 缓存,这个反射调用加载驱动程序的成本应该可以忽略不计。单个SELECT 1 查询将比加载驱动程序字节码贵几个数量级。

【讨论】:

    【解决方案2】:

    从 JDBC 4.0 开始,不再需要执行任何与反射相关的调用来使用 JDBC 驱动程序,因为在您的类路径上发现的任何驱动程序都会自动加载。

    如果您的代码必须支持 JDBC 4 之前的代码,或者如果您的 JDBC 驱动程序位于您的类路径中,则您必须调用 Class.forName 来加载驱动程序。

    在引擎盖下,是否有反射?

    JDBC 4.0 使用Service Provider 机制来定位 JDBC 驱动程序,而无需直接进行反射。但是,在某些时候,需要加载 JDBC 驱动程序类,因此必须执行反射调用。

    【讨论】:

    • 谢谢。一般情况下,当我们动态加载一个.java类文件时,如何消除或隐藏使用反射来访问类中定义的方法,就像JDBC驱动一样?
    • SPI 仍在使用反射,只是在一个包含和预调试的库中。
    • @Ben:让加载的类实现众所周知的接口,就像 JDBC 驱动程序一样。反射只需要实际加载操作;那么它就像任何其他加载的 Java 类一样。
    • @chrylis 谢谢。你能给我一些示例代码的链接吗?
    • @Ben:JDBC 本身。查看您正在使用的 JDBC 接口(在 javax.sql 中)和各种数据库的驱动程序。 Postgres 和 MySQL 的 JDBC 驱动程序是开源的,因此您可以直接检查代码。
    猜你喜欢
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 1970-01-01
    • 2016-10-07
    • 2012-05-16
    • 1970-01-01
    相关资源
    最近更新 更多