Как разделить личные данные пакета между двумя пакетами в Java?

У меня есть 2 пакета Java, A & amp; B. Допустим, некоторые классы в пакете B хотят использовать некоторые классы в пакете A, однако, когда разработчик приходит и разрабатывает пакет C (или, скажем, приложение C), он / она будет использовать мой пакет B, но яdo not хотите, чтобы он / она мог использовать классы в A, которые использует B. То есть я хочу, чтобы мои классы в пакете А были частными, чтобы они были скрыты от разработчика приложения. Однако яdo хочу, чтобы мой собственный пакет B имел доступ к тем классам, которые являются частными. Можно ли это сделать на Java? Нужно ли мне просто кусать пули и делать классы общедоступными и надеяться, что пользователь не попытается их использовать? Или мне нужно повторить классы, которые находятся в A внутри B?

Моим предпочтением было бы то, что не является хакерским (то есть я не хочу использовать рефлексию). Помогите?

 PhD12 июн. 2012 г., 06:37
Почему бы не использовать внутренние классы?
 nhahtdh12 июн. 2012 г., 04:38
Если пакет B может что-то сделать с классами пакета A, то ничто не мешает пакету C делать то же самое с классами пакета A. Однако можно предотвратить получение пакета C экземпляра класса в пакете A, который член класса в пакете B (если нет отражения).
 starbolin12 июн. 2012 г., 05:13
Если вы хотите, чтобы безопасность не кодировала сверху переводчика?
 David12 июн. 2012 г., 06:38
Похоже, пакеты A и B действительно должны быть в одном пакете, или что необходима какая-то фабрика, которая возвращает частную реализацию.
 fatfreddyscat12 июн. 2012 г., 19:21
@nhahtdh - & gt; Не могли бы вы объяснить, как можно, как вы говорите, "предотвратить пакет C от получения экземпляра класса в пакете A, который является членом класса в пакете B"?

Ответы на вопрос(2)

Вы можете сделать это с OSGi. Android и JDK 6 в качестве цели не являются проблемой, в этом случае существуют платформы OSGi, работающие на Android - & gt; например увидетьВстроенный сервер для Android, Вы можете скачать бесплатную некоммерческую версию по ссылке.

У вас есть несколько вариантов, как это сделать в OSGi, в зависимости от того, чего вы хотите достичь.

Вариант 1 (рекомендуется): Вы можете поместить пакеты A и B в один и тот же пакет AB и экспортировать только пакет B в манифест этого пакета с помощью Export-Package. Пакет / приложение C или любой другой «пользователь» Приложение может импортировать пакет B и использовать его. И он не может использовать и даже не видит пакет A, потому что он является внутренним для пакета AB. Вам не нужны какие-либо специальные объявления или зависимости на уровне Java; это будет работать с ЛЮБОЙ версией Jva, потому что модульность и отдельные пространства пакетов являются частью основ OSGi и не зависят от последней версии Java или чего-либо другого.

Вариант 2: Если по какой-либо причине вы хотите, чтобы пакеты A и B были разделены в разных пакетах, вы можете иметь их так, вы экспортируете и импортируете пакеты в манифесте, а затем управляете тем, какой пакет имеет право импортировать какой пакет с помощью разрешений (см. OSGi). Услуги Разрешений и Условных Разрешений). Однако это сложнее понять.

Вариант 3. Вы также можете поместить пакет A в пакет Fragment и позволить ему присоединиться к пакету, содержащему B. Таким образом, B будет иметь доступ к пакету A, но в то же время вы сможете обновить пакет A отдельно. во время выполнения, если хотите. Поскольку пакеты во фрагментах рассматриваются как частные для пакета хоста (в данном случае хост - это пакет, содержащий пакет B), Пакет C не увидит A. Он будет видеть только то, что экспортируется Пакетом B.

Поскольку вы не очень хорошо знакомы с OSGi, я рекомендую запустить вариант 1, а затем при необходимости позже вы можете обновить свой подход до варианта 3, если хотите.

@ Эдвин Далорсо: Это определенно неправда, что правила в OSGi могут быть нарушены отражением. Пакеты имеют отдельные загрузчики классов в OSGi. Вы можете отразить в Bundle C столько, сколько вы выиграете для классов A, и единственное, что вы получите, - это исключение ClassNotFound - поверьте, я видел это достаточно много раз;)

 15 июн. 2012 г., 09:12
Если вы хотите экспортировать только часть пакета A в варианте 1, это также возможно. Используйте & quot; включить & quot; или "исключить" директивы экспорта в записи Export-Package в манифесте: & quot; include & # x2013; Разделенный запятыми список имен классов, которые должны быть видны импортеру. Обратите внимание, что использование запятой в значении требует, чтобы она была заключена в двойные кавычки. Сведения о фильтрации классов см. В разделе «Фильтрация классов» на стр. 50. & quot;
 fatfreddyscat14 июн. 2012 г., 19:14
Спасибо за ваш подробный ответ! В моем случае пакет C должен иметь доступ как к пакету A, так и к пакету B; просто я хочу, чтобы пакет B мог иметь доступ к «частному пакету»; классы внутри A ... Если Java поддерживал концепцию "друга" (как в C ++), тогда это может работать таким образом. Я думаю, что этот подход OSGi может сработать для меня, однако, поскольку у меня жесткие временные ограничения, я, скорее всего, просто воспользуюсь своим «решением для хакерства». (см. мои & apos;UPDATE& APOS; комментарий к моему оригинальному сообщению) сейчас и потом, когда у меня будет время, изучите использование вашего метода. Еще раз спасибо! Голосование вверх!

Вы можете сделать это сJDK 8 И егоПроект Jigsaw, Возможно, вы захотите взглянуть наКраткое руководство по проекту Jigsaw.

К сожалению, Jigsaw является частью JDK8, и он еще не полностью готов. Ожидается, что он не будет завершендо января 2013 и не будет выпущен до середины 2013 года.

Однако вы уже можете скомпилировать свои классы с помощью предварительного просмотра JDK 8 и воплотить свои идеи в жизнь.

В этом случае вашу проблему можно решить, разделив ваше приложение на независимые модули. Вы могли бы сделать что-то вроде:

module foo {
    exports foo;
    permits bar;
    permits baz;
}

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

Не уверен, что альтернативные рамки, такие какOSGI, из которых вы можете найти реализации вАпач Феликс а такжеЗатмение Равноденствие предложить какую-то функциональность для реализации этих уровней инкапсуляции. Вероятно, вы захотите немного изучить это.

Проблема сOSGi Отсутствие Jigsaw заключается в том, что любые правила, применяемые средой, могут быть нарушены отражением, когда Jigsaw будет готов для публичного использования, хотя эти правила будут применяться самой Java, как вы читали выше, во время компиляции, выполнения и установки. время.

 12 июн. 2012 г., 19:35
@fatfreddyscat OSGI, вероятно, ваш лучший способ, но реализовать его будет нелегко.
 02 июл. 2015 г., 09:18
Обратите внимание, что Project Jigsaw не попал в Java 8, теперь он предназначен для Java 9.
 fatfreddyscat12 июн. 2012 г., 19:22
Спасибо за хороший ответ (я проголосовал за это). К сожалению, я нацеливаюсь на Android и JDK 6 ...: / / Есть другие мысли о том, что я мог бы сделать?

Ваш ответ на вопрос