example - jdbc java descargar
¿Cómo funciona Class.forName()? (4)
Cuando creamos un instace de una clase usando un nuevo operador, hace dos cosas
- Cargue la clase en la memoria, si no está cargada, lo que significa que crea una representación en memoria de la clase desde el archivo .class para que se pueda crear una instancia a partir de ella. Esto incluye la inicialización de variables estáticas (resolución de esa clase)
- crea una instancia de esa clase y almacena la referencia a la variable.
Class.forName
solo hace lo primero. Carga la clase en la memoria y devuelve esa referencia como una instancia de Clase. Si queremos crear una instancia, podemos llamar al método newInstance de esa clase. que invocará el constructor predeterminado (sin constructor de argumentos). Tenga en cuenta que si el constructor predeterminado no es accesible, entonces el método newInstance emitirá una IllegalAccessException
. y si la clase es una clase o interfaz abstracta o no tiene un constructor predeterminado, lanzará una InstantiationException
. Si se produce alguna excepción durante la resolución de esa clase, arrojará un ExceptionInInitializerError
.
Si el constructor predeterminado no está definido, entonces debemos invocar el constructor defiend utilizando la API de reflexión.
Pero la principal ventaja con Class.forName es que puede aceptar el nombre de la clase como un argumento de cadena. Entonces podemos pasar el nombre de clase dinámicamente. Pero si creamos una instancia de una clase utilizando un nuevo operador, el nombre de la clase no se puede cambiar dinámicamente.
Class.forName()
inturn llamará al método loadClass del llamador ClassLoader (ClassLoder de la clase desde la que se invoca Class.forName
).
De forma predeterminada, Class.forName()
resuelve esa clase. lo que significa que inicializa todas las variables estáticas dentro de esa clase. lo mismo se puede cambiar utilizando el método sobrecargado de Class.forName(String name,boolean initialize,ClassLoader loader)
La razón principal para cargar el controlador jdbc usando Class.forName()
es que el controlador puede cambiar dinámicamente. en el bloque estático todos los controladores crearán una instancia de sí mismo y registrarán esa clase con DriverManager utilizando el método DriverManager.registerDriver()
. Dado que Class.forName(String className)
resuelve por defecto la clase, inicializará el inicializador estático. Entonces, cuando llamamos a Class.forName("com.sun.jdbc.odbc.JdbcOdbcDriver")
, la clase Driver se cargará, instanciará y registrará con DriverManager
Entonces, si está utilizando un nuevo Operador, debe hacer lo siguiente.
Código:
Driver drv = new com.sun.jdbc.odbc.JdbcOdbcDriver();
DriverManager.registerDriver(drv);
Acabo de enterarme del java.sql package
. Utiliza Class.forName()
para cargar dinámicamente el controlador que extiende DriverManager
. Luego obtenemos conexión usando el método DriverManager.getConnection()
.
Entonces, ¿cómo funciona todo?
¿Cómo sabe la clase DriverManager cómo obtener la conexión sin utilizar el nombre de clase del controlador real?
También podemos usar Class.forName () para aplicaciones personalizadas ... si esto se explica con un ejemplo, estaré muy contento.
La razón por la cual Class.forName()
se menciona con frecuencia en los ejemplos de SQL, se debe a que no había magia para decirle al DriverManager JDBC cómo mapear la URL JDBC proporcionada a un controlador real.
Por ejemplo, "mysql" debe asignarse a una clase MySQL determinada, mapas "delgados" a la clase Oracle, mapas "as400" a la clase DB2 / 400.
Al cargar explícitamente la clase, esto permitió que se ejecutara el código dentro de la clase que se registra con el DriverManager.
En la actualidad, los ganchos mágicos están presentes, lo que permite a la JVM detectar automáticamente los controladores (si son lo suficientemente nuevos) por lo que la llamada es superflua, pero por costumbre todavía la usan.
Class.forName(..)
carga e inicializa la clase de destino. Esto a su vez significa que se invocan los bloques de inicializador estático (código definido en static { .. }
.
Si observa, por ejemplo, el controlador de MySQL, en ese bloque estático el controlador se está registrando: DriverManager.registerDriver(new Driver());
Puede omitir Class.forName(..)
y registrar el controlador usted mismo si puede "pagar" la dependencia en tiempo de compilación del controlador de MySQL.
Dicho esto, rara vez será relevante usar Class.forName(..)
para inicializar clases desde su aplicación, porque la dependencia del tiempo de compilación no es un problema.
También tenga en cuenta que Class.forName(..)
DriverManager para JDBC desde la versión 4. Al utilizar el mecanismo del proveedor de servicios, puede indicar al administrador del controlador qué cargar con una propiedad del sistema.
Class.forName
simplemente carga una clase, incluso ejecuta sus inicializadores estáticos, como este:
class Foo {
static {
System.out.println("Foo initializing");
}
}
public class Test {
public static void main(String [] args) throws Exception {
Class.forName("Foo");
}
}
Todo el resto del procedimiento del que está hablando es específico de JDBC. El controlador - que implementa Driver
, no extiende DriverManager
- simplemente registra una instancia apropiada usando DriverManager.registerDriver
. Luego, cuando DriverManager
necesita encontrar un controlador para una cadena de conexión en particular, llama a acceptsURL
en cada controlador registrado por turno hasta que uno dice: "Sí, puedo ser el controlador para esa conexión".
Tenga en cuenta que esta forma de registrar controladores está razonablemente pasada de moda: consulte los documentos de DriverManager
para obtener formas más modernas de acceder a una fuente de datos.