Здравствуйте, Palmovod, Вы писали:
P>Что происходит, когда выполняется Class.forName("некоторый класс") ?
public static Class<?> forName(String className) throws ClassNotFoundException
Returns the Class object associated with the class or interface with the given string name. Invoking this method is equivalent to:
Class.forName(className, true, currentLoader)
where currentLoader denotes the defining class loader of the current class.
For example, the following code fragment returns the runtime Class descriptor for the class named java.lang.Thread:
Class t = Class.forName("java.lang.Thread")
A call to forName("X") causes the class named X to be initialized.
Parameters:
className — the fully qualified name of the desired class.
Returns:
the Class object for the class with the specified name.
Throws:
LinkageError — if the linkage fails
ExceptionInInitializerError — if the initialization provoked by this method fails
ClassNotFoundException — if the class cannot be located
Здравствуйте, Palmovod, Вы писали:
P>Что происходит, когда выполняется Class.forName("некоторый класс") ?
Ищется класс в ClassLoader, если не найден, то он ищется в текущем класслоадере (в том, которым был загружен тот класс, откуда был вызван этот метот), потом он загружается, инициализируется и отдается. Если не найден — ClassNotFound будет.
Здравствуйте, Palmovod, Вы писали:
P>Т.е. если класс найден, то будет создан экземпляр этого класса (включая выполнение конструктора класса, инициализацию полей) ?
Нет, будет создан instance типа java.lang.Class. Инстанциирование самого загруженного класса.
Чтобы создать из него объект, надо у него дернуть метод newInstance или вытащить constructor и дернуть его.
А с практической т.з. зачем надо делать Class.forName(...) ? Например при использовании JDBC драйвер (класс) загружают именно таким образом. Почему бы просто не создать экземпляр класса?
Здравствуйте, Palmovod, Вы писали:
P>А с практической т.з. зачем надо делать Class.forName(...) ? Например при использовании JDBC драйвер (класс) загружают именно таким образом. Почему бы просто не создать экземпляр класса?
Его может не быть в classpath, на момент компиляции, вы не знаете какой драйвер вам надо загружать.
К тому же там есть JDBCшный глюк, связанный со статической инициализацией. Драйвер при загрузке должен сам себя прописать (DriverManager.registerDriver). Поэтому делают Class.forName, а драйвер в статическом блоке сам себя создает и прописывает.
Плюс ко всему — это не очень хорошая практика инициализации драйвера.
JDBC дравера лучше указывать в одном месте, в свойстве jdbc.drivers
Здравствуйте, aefimov, Вы писали:
A>Плюс ко всему — это не очень хорошая практика инициализации драйвера. A>JDBC дравера лучше указывать в одном месте, в свойстве jdbc.drivers A>http://javaalmanac.com/egs/java.sql/LoadDrivers.html
Забавно, но по ссылке утверждается обратное.
Здравствуйте, aefimov, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
A>>>http://javaalmanac.com/egs/java.sql/LoadDrivers.html А>>Забавно, но по ссылке утверждается обратное.
A>Да, но почему — непонятно. A>Хардкодить имена классов и рекумендуют. Странно
Ну, во-первых javaalmanac не является истиной в последней инстанции.
На счет хардкода можно лишь предположить — разработчик может допускать меньше ошибок в коде, нежели пользователь в командной строке.
(Про скрипты запуска я здесь умолчу, ибо это лишь предположение.)
// Artem
/* Walking on water and developing software
from a specification are easy if both are frozen.
(c) Edward V. Berard */
Здравствуйте, Metral, Вы писали:
M>Ну, во-первых javaalmanac не является истиной в последней инстанции. M>На счет хардкода можно лишь предположить — разработчик может допускать меньше ошибок в коде, нежели пользователь в командной строке. M>(Про скрипты запуска я здесь умолчу, ибо это лишь предположение.)
Согласись, то прописать новый драйвер в конфиге файле и положить jar в lib проще, чем менять код?
Здравствуйте, aefimov, Вы писали:
A>Согласись, то прописать новый драйвер в конфиге файле и положить jar в lib проще, чем менять код?
Для меня — безусловно
// Artem
/* Walking on water and developing software
from a specification are easy if both are frozen.
(c) Edward V. Berard */
Здравствуйте, Palmovod, Вы писали:
P>Т.о. использование Class.forName(...) позволяет обновлять части программы (например в случае с драйверами JDBC) без перекомпиляции самой программы?
а вы поэкспериментируйте!
создайте класс, запакуйте его в jar, используйте два варианта для получения инстанса класса — hardcoded и dynamic. запустив приложение, обратите внимание на поведение; затем измените свой класс, и вновь скопмилировав и упаковав его в jar, запустите прилоежние вновь (только основное приложение не перекомпилируйте, для чистоты эксперимента). BTW, не забудь-те про classpath