#java #intellij-idea #jar
#java #intellij-идея #jar
Вопрос:
Я создаю библиотеку. У меня есть три пакета:
Электронная таблица — это основной пакет. Пакет ввода-вывода — это внутренний пакет для внутреннего использования. К сожалению, пользователь может получить к ним доступ, поскольку они являются общедоступными классами.
Я хотел бы сохранить этот пакет, поскольку он позволяет мне разделять концепции во время программирования, но я хотел бы «скрыть» эти классы для конечного пользователя.
Что я мог сделать?
Комментарии:
1. Где используются эти два класса Ods *?
2. @LppEdd в классе электронных таблиц
Ответ №1:
Хорошо, что вы задаете себе этот вопрос! В последнее время я не вижу особого внимания к этому.
Поскольку OdsReader
и OdsWriter
используются только внутри Spreadsheet
класса, просто переместите их внутрь spreadsheet
пакета, удалив ключ для public
видимости. Теперь они будут доступны только из spreadsheed
классов пакета.
Предложенное выше решение, которое является чрезмерно сложным для вашего варианта использования и которое заключается в использовании Java 9
модулей (или OSGi — пожалуйста, нет!), на самом деле здесь не обязательно, но, тем не менее, это шаг вперед в сохранении определений частными и запечатанными, даже для Reflection
нарушителей.
В качестве дополнительного примечания, я вижу, у вас есть exceptions
пакет.
Я никогда не рекомендую этого делать, поскольку вам придется предоставить конструктор этих исключений пользователям вашего кода, и они смогут создавать их экземпляры без каких-либо веских причин.
Переместите исключения внутри пакетов, которые их используют, и объявите конструктор как package private.
Комментарии:
1. Да, в этом случае полное удаление
io
пакета (и перенос этих классов в основнойspreadsheet
пакет) — гораздо более простой способ получить желаемый результат. Однако такое мышление обычно приводит к представлению о том, что в конечном итоге проект будет содержать все классы в одном пакете, что является довольно плохим способом попытаться выполнить разделение обязанностей внутри проекта.2. @rzwitserloot Нет, это не приводит к этому, если архитектура хорошая. Я работал в крупных проектах, где использовалась эта технология, и они были идеально структурированы. В этом случае проект небольшой, и он идеально подходит. Не нужно перепроектировать (например, с помощью загрузчиков классов)
Ответ №2:
Начиная с java9, вы можете превратить эту библиотеку в модуль. Смотрите это руководство по jigsaw.
Модулям необходимо экспортировать пакет, чтобы его общедоступные элементы были доступны из других модулей: просто не экспортируйте свой внутренний пакет, и он не будет виден.
Вы также можете использовать что-то вроде OSGi, модульной системы, которая предшествовала java9. В нем тоже есть представление о том, что существует уровень за пределами public (давайте назовем его «видимым»).
Последний вариант — использовать махинации с загрузчиком классов (где вы, например, переименовываете свои файлы классов в какое-либо другое расширение на этапе сборки и имеете небольшой загрузчик в вашем пакете visible, который создает загрузчик классов, который загружает классы, просматривая то же место, что и visible API, а затем загружает файлы с альтернативным расширением, и defineClass
они создаются), но это решительный шаг, который вызывает довольно много головной боли. Я бы не стал за это браться, если у вас нет веских причин лезть в эту кроличью нору.