Поскольку мы знаем, что оператор package при запуске командой javac создает связанные каталоги в соответствии с именем пакета.
Например:
// MyClassB.java
package abc.xyz;
class MyClassA{
// ...
}
class MyClassB{
// ...
}
Теперь, когда я компилирую этот файл:
javac -d . MyClassB.java
После компиляции у нас будет следующая структура каталогов с файлами .class.
/
|___ abc
|___ xyz
|___ MyClassA.class
|___ MyClassB.class
Теперь вопрос: эти MyClassA.class и MyClassB.class содержат только скомпилированный байткод классов MyClassA и MyClassB?
А как насчет следующего утверждения?
package abc.xyz;
Этот оператор удаляется во время компиляции? Или это утверждение удаляется только из класса MyClassA и остается в классе MyClassB, потому что имя файла было MyClassB.java. А может, файл MyClassB.class после компиляции содержит только байт-код класса MyClassB, а package abc.xyz; тоже удаляется при компиляции? Если package abc.xyz; не будет удален во время компиляции, это будет проблемой, когда мы будем использовать этот файл во время выполнения, потому что механизм выполнения также вызовет версию байт-кода инструкции package abc.xyz;, поэтому, это было бы проблемой. Или он удаляется при компиляции? Или байт-код создается только для классов, а не для файла, содержащего инструкцию package abc.xyz;, в результате чего package abc.xyz; не становится частью файлов .class .
Картинка ниже ясно объясняет вопрос:
Кто-нибудь может объяснить, что за сценарий стоит за этим? Это моя скромная просьба к участникам не ставить отрицательную оценку моему вопросу, потому что у меня есть некоторые недоразумения относительно java, поэтому я хочу прояснить свою концепцию. Если мой вопрос все еще может быть отмечен отрицательной оценкой, тогда все в порядке, но, по крайней мере, ответьте также.
Спасибо !!!
Я имею в виду, что целью оператора package abc.xyz; является создание каталогов и размещение файлов .class внутри каталога xyz, поэтому время выполнения будет выполнять ту же работу, что и время компиляции? Так не в этом ли проблема? Поскольку среда выполнения скажет, давайте создадим каталоги из-за оператора package abc.xyz;, так что, как я понимаю, теперь я не знаю, что за сцена стоит.
Пусть говорит, что у меня есть выписка System.out.print("Hello world");. Теперь, когда эта программа запустится, Hello World будет распечатан, верно? Допустим, у меня есть оператор package abc.xyz;. Теперь, когда эта программа запустится, она снова создаст каталоги и файлы .class? я надеюсь, что вы получили меня сейчас !!! Я говорю о времени выполнения.
Нет, это процесс сборник, который создает файлы классов. Это полностью отличается от того, что происходит, когда вы запускаете код.
«Я имею в виду, что цель оператора package abc.xyz; состоит в том, чтобы создать каталоги и поместить файлы .class в каталог xyz» - нет, это указать пакет для классов, объявленных в этом исходном файле. Это не «код, который работает». Именно компилятор решает, что ему делать с файлами классов. Другой компилятор может вообще не использовать файловую систему, но ему все равно нужно знать пакет класса.




Он нигде не идти, он скомпилирован как class abc.xyz.MyClassA. Вы можете видеть это, если бы вы декомпилировали этот .class, например, используя javap.
Но результатом оператора package abc.xyz; является создание каталогов и размещение файла .class в каталоге. Итак, не будет ли среда выполнения создавать каталог снова и снова при запуске этой программы, разве это не проблема? или оператор package abc.xyz; не выполняется во время выполнения?
Пусть говорит, что у меня есть выписка System.out.print("Hello world");. Теперь, когда эта программа запустится, Hello World будет распечатан, верно? Допустим, у меня есть оператор package abc.xyz;. Теперь, когда эта программа запустится, она снова создаст каталоги и файлы .class? я надеюсь, что вы получили меня сейчас !!! Я говорю о времени выполнения.
@SunnyKhan «запускает» уже скомпилированные классы, они не компилируются снова. вы понимаете это правильно?
Итак, package abc.xyz; не является частью среды выполнения?
package abc.xyz: только проверяет, находитесь ли вы в правильном каталоге, если вы не компилятор или текстовый редактор ide скажет что-то вроде имя пакета не совпадает с именем каталога снова package abc.xyz:НИЧЕГО не создает, это похоже на приведение --> допустим, класс собака расширяет класс животного, которого вы можно написать что-то вроде Animal a = new Dog(); и тогда вы могли бы написать Dog d = (Dog) a; если бы a было каким-то другим животным, например a=new Cat(); вы получите ошибку времени компиляции
Приведение Часть 2 не изменяет объект, он не превращает его в собаку, он аналогичен пакету, он только там, чтобы проверить, находится ли ваш файл в правильном каталоге.
Если вы откроете файл .class любого вашего класса, вы увидите внутри него детали пакета. В вашем случае, если вы откроете MyClassA.class в текстовом редакторе, то увидите что-то вроде abc/xyz/MyClassA. JVM будет использовать его как abc.xyz.MyClassA. Вот почему, если нам нужно использовать этот класс в каком-то другом классе, нам нужно использовать его, как import abc.xyz.MyClassA.
Пусть говорит, что у меня есть выписка System.out.print("Hello world");. Теперь, когда эта программа запустится, Hello World будет распечатан, верно? Допустим, у меня есть оператор package abc.xyz;. Теперь, когда эта программа запустится, она снова создаст каталоги и файлы .class? я надеюсь, что вы получили меня сейчас !!! Я говорю о времени выполнения.
Пакет используется для группировки типов Java (классы, интерфейсы, перечисления и т. д.). Поэтому, когда вы используете пакет в своей Java-программе, он связывает эти типы Java в одном пакете.
Пожалуйста, прочитайте это от оракула для получения более подробной информации. Пакеты
Такие директивы, как объявление package, а также операторы import, вообще не генерируют никакого кода, они только влияют на то, как компилятор будет обрабатывать имена в пределах одной единицы компиляции.
Итак, объявление типа
package abc.xyz;
public class MyClassA {
}
создает класс с полным именем abc.xyz.MyClassA или класс с простым именем MyClassA в пакете abc.xyz; оба означают одно и то же.
Полное имя хранится в файле .class, который является единственной важной информацией для JVM.
Существует соглашение для хранения такого файла, как SimpleName.class, в каталоге, полученном из имени пакета, то есть abc/xyz/MyClassA.class, привязанного javac и используемого стандартными загрузчиками классов для поиска файла, когда запрашивается класс с таким именем. Очевидно, что наличие такого соглашения облегчает жизнь.
В принципе возможны и другие способы хранения, и некоторые из них известны. Начиная с Java 9 эталонная реализация имеет формат образа модуля, до этого был «архив данных общего класса», далее был «Pack200», формат архива, который устарел для удаления с JDK 11.
Обратите внимание, что даже jar-файлы, которые представляют собой расширенные zip-файлы, — это не совсем то, что вы видите. ZIP-файл состоит из линейной последовательности файловых записей, имеющих полное имя, поэтому в вашем случае у вас будет две записи, сообщающие свои имена как abc/xyz/MyClassA.class и abc/xyz/MyClassB.class, тогда как любая структура каталогов, отображаемая инструментами, фактически получена из этих имен и не подразумевает, что вложенные записи для abc и xyz действительно существуют. Тем не менее, стандартный загрузчик классов также будет использовать эти записи так же, как если бы эта структура каталогов существовала, поэтому нет проблем с сохранением структуры каталогов в файле zip/jar.
Но, начиная с Java 9, для одного и того же класса могут быть разные версии, которые следует выбирать в зависимости от текущей версии Java. Схема именования, используемая для этого, не является частью соглашения, используемого javac при хранении файлов.
В самом деле? структура файлов jar может не существовать, и такая структура папок получена из фактического имени?
@Eugene имя записи zip-файла, не обязательно фактическое имя класса. Это означает, что вы можете создать zip-файл, например. через ZipOutputStream, создайте одну запись через putNextEntry с именем foo/bar/baz, и когда вы откроете ее с помощью файловой системы zip или аналогичного инструмента, ориентированного на файловую систему, он покажет вам каталог foo, содержащий каталог bar, содержащий файл baz, тогда как zip-файл имеет только одну запись. Обычно zip-файлы вообще не содержат записей для каталогов.
Пожалуйста, не могли бы вы пояснить эту фразу? " Если пакет abc.xyz; не удален во время компиляции, тогда это будет проблемой, когда мы будем использовать этот файл во время выполнения, потому что механизм выполнения также вызовет версию байт-кода инструкции пакета abc.xyz;, поэтому будет проблема." Что вы подразумеваете под «версией байт-кода оператора пакета abc.xyz триггера»?