Подтвердить что ты не робот

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

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

    package abraKadabra;

    public class SuperClass{
       protected int anInstance;

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

Однако этот файл находится в следующей структуре папок:

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

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

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

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

4b9b3361

Ответ 1

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

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

    package mySample;


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

Этот файл находится в каталоге "D:\Code N Code\CommandLine".

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

    javac -d . Sample.java

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

Итак, если бы я дал имя моего пакета "package com.mySample", компилятор создавал бы два каталога и помещал бы мой файл класса в "D:\Code N Code\CommandLine\com\mySample".

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

    java mySample.Sample

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

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

Ответ 2

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

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

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

Ответ 3

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

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

Ответ 4

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

package abraKadabra;

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