Имя пакета отличается от структуры папок, но все же код Java компилируется

Я использую Notepad++ для написания кода Java и командной строки для его компиляции и запуска. Ниже мой пример кода Java,

    package abraKadabra;

    public class SuperClass{
       protected int anInstance;

       public static void main(String [] abc){
           System.out.println("Hello");
       }
    }

однако этот файл имеет следующую структуру папок:

"usingprotectedsuperPkg" (usingProtected-это папка где-то в иерархии в C:)

Итак, мое имя пакета здесь должно быть чем-то вроде usingProtected.superPkg вместо abraKadabra, как я его написал.

но, когда я компилирую эту Java код из командной строки, он компилируется нормально без ошибок или предупреждений. Почему это так? Не должно ли имя пакета соответствовать структуре папок? И если да, то как он будет держаться?

например, если мое имя пакета usingProtected.superPkg, будет ли компилятор проверять в обратном порядке. Настоящий рабочий каталог должен быть superPkg, затем родительский каталог должен быть usingProtected и его Сделано. Это то, как он проверяет структуру папок с именем пакета?

4 ответов


спецификация языка Java не заставляет файлов в определенном каталоге. Это необязательно позволяет компилятор требует, чтобы общественные классы являются в файлах с тем же именем класса, но я не думаю, что есть что-то подобное для пакетов. 7.2.1 говорит о возможных вариантах хранения в файловой системе, но, насколько я вижу, ничего не говорит о применении структуры исходного кода.

тем не менее, это лучшая практика - и в значительной степени общепринятое соглашение-отразить структуру пакета в исходной структуре каталогов... а javac будет используйте это, чтобы попытаться найти исходные файлы, которые явно не указаны для компиляции.

обратите внимание, что если вы компилируете из командной строки, по умолчанию каждый класс будет отображаться в том же месте, что и соответствующий исходный файл, но если вы используете опцию "-d" (например, "- D bin"), компилятор построит соответствующий вывод структура каталогов для вас, укорененная в указанном каталоге.


после экспериментов немного, я получил способ, как использовать имя пакета и запускать файлы классов Java из командной строки.

предположим, что мой исходный файл Java: -

    package mySample;


    public abstract class Sample{
        public static void main(String... a){
           System.out.println("Hello ambiguity");
        }
    }

этот файл находится в каталоге "D:\Code N код\Командная строка".

Теперь, при компиляции исходного кода (перейдя в вышеуказанный каталог из cmd), используя следующую команду: -

    javac -d . Sample.java

это автоматически создает папку" mySample " в моем текущем каталоге. Итак, мой файл класса Образец.класс присутствует в каталоге "D:\Code N код\Командная строка\mySample". Компилятор создал эту новую папку "mySample" из имени пакета, которое я дал в своем исходном коде.

поэтому, если бы я дал свое имя пакета " пакет com.mySample", компилятор создаст два каталога и разместит мой файл класса в "D:\Code N код\Командная строка\com\mySample".

Теперь я все еще в настоящем рабочем каталоге, т. е. в "D:\Code N код\Командная строка". И чтобы запустить мой файл класса, я даю следующая команда:

    java mySample.Sample

Итак, я даю полную иерархию пакета и имя класса. Интерпретатор Java будет искать текущий каталог для каталога " mySample "и в этом для" образца.класс." Он получает его правильно и успешно работает. :)

Теперь, когда я спросил, почему он компилирует мой неправильный исходный код пакета, он скомпилирует код успешно, но он дает NoClassDefFoundError при запуске файла класса. Так выше метод можно использовать использование имен пакетов из командной строки.


Если вы компилируете один класс, javac не нужно искать его в другом месте. Он просто скомпилирует файл как есть и поместит полученный .class в ту же папку. Однако вы обычно не сможете использовать класс, пока не поместите его в каталог "abraKadabra" в одном из каталогов в пути к классу.

Если ваш класс использует другой класс в пакете, у вас могут возникнуть проблемы с компиляцией его там, где он есть, по той же причине (javac хочет найти класс и убедитесь, что у него есть методы и такие, которые использует ваш класс).


Java-компилятор не проверяет структуру каталогов при компиляции исходных файлов. Как вы упомянули, у вас есть исходный файл, который начинается с директивой

package abraKadabra;

можно скомпилировать файл, даже если он не содержится в поддиректории ...абракадабра . Исходный файл будет компилироваться без ошибок, если он не зависит от других пакетов. Однако результирующая программа не будет запущена. Виртуальная машина не найдет результирующие классы при попытке запустить программа.