Когда мы создаем класс с помощью оператора new, он делает две вещи
- Загрузить класс в память, если он не загружен -
это означает создание представления класса в памяти из файла .class, чтобы из него можно было создать экземпляр. Это включает инициализацию статических переменных (разрешение этого класса)
- создать экземпляр этого класса и сохранить ссылку на переменную.
Class.forName
делает только первое.
Он загружает класс в память и возвращает эту ссылку как экземпляр класса. Если мы хотим создать экземпляр, мы можем вызвать метод newInstance этого класса. который вызовет конструктор по умолчанию (без аргумента конструктора).
Обратите внимание, что если конструктор по умолчанию недоступен, метод newInstance выдаст IllegalAccessException
. и если класс является абстрактным классом или интерфейсом или у него нет конструктора по умолчанию, тогда он выдаст InstantiationException
. Если какое-либо исключение возникает во время разрешения этого класса, оно выдаст ExceptionInInitializerError
.
Если конструктор по умолчанию не определен, то мы должны вызвать конструктор defiend, используя API отражения.
Но главное преимущество Class.forName заключается в том, что он может принимать имя класса в качестве аргумента String. Таким образом, мы можем передать имя класса динамически. Но если мы создаем экземпляр класса с помощью оператора new, имя класса нельзя изменить динамически.
Class.forName()
inturn вызовет метод loadClass вызывающего ClassLoader (ClassLoder класса, из которого вызывается Class.forName
).
По умолчанию Class.forName()
разрешает этот класс. что означает, инициализировать все статические переменные внутри этого класса.
то же самое можно изменить, используя перегруженный метод Class.forName(String name,boolean initialize,ClassLoader loader)
Основная причина загрузки драйвера jdbc с помощью Class.forName()
заключается в том, что драйвер может динамически меняться.
в статическом блоке все Драйверы создадут свой экземпляр и зарегистрируют этот класс в DriverManager, используя метод DriverManager.registerDriver()
. Поскольку Class.forName(String className)
по умолчанию разрешает класс, он инициализирует статический инициализатор.
Поэтому, когда мы называем Class.forName("com.sun.jdbc.odbc.JdbcOdbcDriver")
,
класс Driver будет загружен, создан и зарегистрирован в DriverManager
Так что, если вы используете новый оператор, вы должны сделать следующее:
Код:
Driver drv = new com.sun.jdbc.odbc.JdbcOdbcDriver();
DriverManager.registerDriver(drv);