Прежде всего, этот тест не будет работать в Java 9 или новее. Попытка скомпилировать класс String
приведет к этой ошибке:
java/lang/String.java:1: error: package exists in another module: java.base
package java.lang;
^
На Java 8 я получаю поведение, которое вы видите. Предполагая, что измененный класс String
находится в том же дереве исходного кода, класс Main
компилируется, но выдает исключение при попытке его запустить.
Это, как представляется, сообщается как ошибка 4929425 . Решением было то, что это была ошибка документации, и они уточнили документацию для команды javac
... хотя, возможно, этого недостаточно.
Во всяком случае, есть разница, и она тонкая.
Команда java
просто ищет в следующем порядке:
- путь начальной загрузки
- каталоги расширений
- 1024 * Путь к классам *
Команда javac
сначала ищет исходный каталог. Если он находит там исходный файл, он ищет соответствующий файл класса в том же месте и (при необходимости) компилирует или перекомпилирует его. Если исходный файл не найден, он ищет пути к классам для файла класса, как описано выше для java
.
Обратите внимание, что требуется очень осторожное чтение ручной записи javac
, чтобы выявить это. Это легко пропустить. (https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#searching)
(IMO, они могут сделать страницу руководства более понятной. Однако это несоответствие имеет значение только в том случае, если вы пытаетесь переопределить какой-либо класс в пути начальной загрузки или в каталоге расширений. И вы делаете это неправильно. В основном Это крайний случай. Проблема с четким документированием непонятных крайних случаев заключается в том, что вы можете сделать документацию более запутанной для обычного случая.)