Ответ 1
Да, по умолчанию он использует классы из первой банки. Вот почему вам нужно проверить библиотечный каталог для дубликатов. Так много раз для меня и моих коллег.
Это была ошибка моего коллеги: там была банка с именем test.jar, и он исправил ее ошибку. Затем он перекомпилирует код и построил новую банку с именем testnew.jar Проблема заключалась в том, что он поставил эти две банки в одну папку, которая в classpath. Поэтому, когда программа работала, поведение было своего рода беспорядком. Я не знал, что произошло, но после удаления test.jar все было в порядке.
Так что мне интересно, что такое поведение JVM. Использует ли он файл класса в первой банке, с которой он встречается? Или что-то другое?
Спасибо.
Да, по умолчанию он использует классы из первой банки. Вот почему вам нужно проверить библиотечный каталог для дубликатов. Так много раз для меня и моих коллег.
Насколько я могу судить, он не определен.
Java имеет подключаемую систему загрузчика классов, и, таким образом, единственный способ узнать, что произойдет, - посмотреть документацию ClassLoader
class, возможно, в частности метод ClassLoader#findClass
, который не определяет поведение для этого, и посмотрите на соответствующие разделы JLS и спецификации JVM, ни один из которых не указывает ограничение на загрузчики классов в этом отношении. Таким образом, если поведение не документировано загрузчиком классов, используемым вашим веб-контейнером, вы не можете точно знать, какой класс будет загружен.
Скорее всего, первый найденный, который соответствует двоичному имени класса, будет загружен, но существует большая разница между поведением, которое, как мы полагаем, имеет место, и поведение, которое указанным и/или документированным.
Если есть дубликаты, он читает тот, который появляется первым в вашем пути к классам.
Edit Файл classpath вообще выглядит примерно так.
<classpath>
<classpathentry kind="lib" path="C:/Temp/test.jar"/>
<classpathentry kind="lib" path="C:/Temp/testnew.jar"/>
<classpathentry kind="output" path="build/classes"/>
</classpath>
Если ваш путь к классам выглядит примерно так, ваш JVM сначала рассмотрит test.jar, так как он появится сначала в пути к классам. Если вы хотите протестировать его самостоятельно, попробуйте переместить classpathentry для testnew.jar над входом test.jar. Вы увидите, что теперь он ссылается на testnew.jar вместо test.jar.
Ссылка: FindingClasses
JVM загружает все определенные JAR файлы в путь к классам. Так как java 6 также имеет подстановочный знак. Ниже приведены несколько примеров.
java -cp ".:lib/example.jar" Main
Вышеуказанное будет загружать только классы, найденные в текущем каталоге и внутри example.jar. Если следующий пример будет использовать любой jar для загрузки классов из.
java -cp ".:lib/*" Main
Я не думаю, что порядок, для которого jar в каталоге проверяется первым, чтобы найти класс, определен, который когда-либо заказывал ОС при перечислении файлов.
Скорее всего, ваша IDE (или что-то, что вы используете для запуска вашей программы) использует последнюю нотацию для запуска вашей программы. Вы можете изменить его так, чтобы он использовал первый, хотя он сломается, если вы когда-либо измените имя фляги или добавите новые.