Ответ 1
Я думаю, что вопрос, который вы, возможно, пытаетесь задать, - "Что такое пакеты на Java и как относится к ним ключевое слово import
?" . Ваша путаница в структурах каталогов может быть связана с тем, что на некоторых других языках есть директивы include
, которые используют имена файлов, чтобы буквально включать содержимое указанного файла в исходный код во время компиляции. C/С++ - примеры языков, которые используют этот тип директивы include
. Java import
не работает таким образом. Как говорили другие, ключевое слово import
- это просто сокращенный способ ссылки на один или несколько классов в пакете. Реальная работа выполняется загрузчиком классов Java Virtual Machine (подробнее см. Ниже).
Начнем с определения "пакета Java", как описано в статье Википедии:
Пакет Java - это механизм для организация классов Java в пространства имен, подобные модулям Modula. Пакеты Java могут быть сохранены в сжатые файлы, называемые JAR файлами, позволяя классам загружаться быстрее, чем группа, а не одна за раз. Программисты также обычно используют пакеты для организации классов к той же категории или предоставлению аналогичная функциональность.
В Java файлы исходного кода для классов фактически организованы по каталогам, но метод, с помощью которого виртуальная машина Java (JVM) находит эти классы, отличается от таких языков, как C/С++.
Предположим, что в вашем исходном коде есть пакет с именем "com.foo.bar", и внутри этого пакета у вас есть класс с именем "MyClass". Во время компиляции местоположение исходного кода этого класса в файловой системе должно быть {source}/com/foo/bar/MyClass.java
, где {source}
является корнем исходного дерева, которое вы компилируете.
Одно из различий между Java и языками, такими как C/С++, - это концепция загрузчика классов. На самом деле концепция загрузчика классов является ключевой частью архитектуры виртуальной машины Java. Задача загрузчика классов - найти и загрузить любые файлы class
, которые требуется вашей программе. "Первоначальный" или "по умолчанию" загрузчик классов Java обычно предоставляется JVM. Это обычный класс типа ClassLoader
и содержит метод loadClass()
со следующим определением:
// Loads the class with the specified name.
// Example: loadClass("org.apache.nutch.plugin.Extension")
Class loadClass(String name)
Этот метод loadClass()
попытается найти файл class
для класса с заданным именем и выдает class
объект, который имеет newInstance()
метод, способный создавать экземпляр класса.
Где загружает загрузчик классов для файла class
? В пути класса JVM. Путь к классу - это просто список мест, где можно найти файлы class
. Эти локации могут быть каталогами, содержащими class
файлы. Он может содержать даже jar
файлы, которые могут содержать даже больше class
файлов. По умолчанию загрузчик классов способен искать внутри этих файлов jar
для поиска файлов class
. В качестве дополнительной заметки вы можете реализовать свой собственный загрузчик классов, чтобы, например, разрешить поиск местоположений сети (или любого другого местоположения) для файлов class
.
Итак, теперь мы знаем, что "com.foo.bar.MyClass" находится в файле class
в вашем собственном исходном дереве или файле class
внутри файла jar
где-то в пути вашего класса, загрузчик класса найдет его для вас, если он существует. Если он не существует, вы получите ClassNotFoundException
.
И теперь для обращения к ключевому слову import
: Я расскажу о следующем примере:
import com.foo.bar.MyClass;
...
public void someFunction() {
MyClass obj1 = new MyClass();
org.blah.MyClass obj2 = new org.blah.MyClass("some string argument");
}
Первая строка - это просто способ сообщить компилятору "Всякий раз, когда вы видите переменную, объявленную просто как тип MyClass
, предположим, что я имею в виду com.foo.bar.MyClass
. Это то, что происходит в случае obj1
. obj2
, вы явно говорите компилятору" Мне не нужен класс com.foo.bar.MyClass
, я действительно хочу org.blah.MyClass
". Таким образом, ключевое слово import
- это просто простой способ сократить количество ввода программисты должны делать, чтобы использовать другие классы. Все интересные вещи выполняются в загрузчике классов JVM.
Для получения дополнительной информации о том, что делает загрузчик класса, я рекомендую прочитать статью под названием Основы загрузчиков классов Java