Скрытие классов в файле jar

Неужели невозможно скрыть некоторые классы в файле jar?

Я хотел не допускать прямого экземпляра классов, чтобы он был более гибким. В этом банке должны быть видны только factory (или фасад).

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

Ответ 1

Я думаю, что у вас будет либо сбой компилятора, либо предупреждение, если ваш общедоступный метод factory попытается вернуть что-то, что "скрыто".

Нет, вы не можете скрыть открытый класс без переопределения собственного ClassLoader или использования OSGi или чего-то подобного.

Что вы можете сделать, так это отделить интерфейс api от реализации, например. имеют один проект, который содержит только интерфейсы и другой файл, содержащий импликации. Однако вы все еще не можете скрыть классы реализации.

Ответ 2

Я понимаю, что вы не хотите скрыть фактические классы, просто запретите их строительство вне класса factory. Это, я думаю, может быть довольно легко достигнуто за счет использования прозрачной видимости пакета (по умолчанию) в конструкторах классов. Единственное ограничение состоит в том, что вам нужно будет иметь классы и factory в одном пакете, поэтому в среде с большой и большой кодовой базой вещи могут оказаться излишне сложными.

Ответ 3

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

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

  • Вы можете сделать все свои классы в частные внутренние классы factory. Это будет работать, если бы у вас было один factory за класс, но вряд ли работоспособны, если у вас много управление различными классами через один factory.
  • Вы можете использовать модификатор доступа protected для ограничить доступ к вашему классу Конструкторы. Это обычное практика при использовании factory шаблон.

Ответ 4

Obfuscation может помочь вам как-то.

Ответ 5

С обычными загрузчиками классов простые старые файлы jar это невозможно. OSGi использует эту концепцию, чтобы сделать видимым для другого пакета только некоторые пакеты, а не другие (то есть разделение public api и внутренней реализации).

Если вы затмение usinf, вы можете применять такие правила с помощью this

Ответ 6

Если вы правильно поняли, когда говорите "не позволять прямому инстанцированию классов, чтобы он был более гибким", правильно обработанный шаблон фасада справится с этим.

Ограничьте конструкторы всех классов, которые вы хотите скрыть, в область пакета. Откройте класс фасада в общественном масштабе.

http://mindprod.com/jgloss/packagescope.html

"Если у вас есть переменная или метод в ваш класс, который вы не хотите клиентов вашего класса, непосредственно доступного, не давайте ему публичный, защищенный или частная декларация. Из-за надзор за дизайном Java, вы can not явно объявляет значение по умолчанию доступность пакета. Другие члены пакета сможет увидеть его, но классы вне пакета, которые наследовать от вашего, не будет. атрибут защищенной доступности предлагает немного больше видимости. защищенный метод наследования классов, даже не являющихся частью тот же пакет. Объем пакета (по умолчанию) нет. Это только разница между защищенными и объем упаковки."

Ответ 7

Есть два решения вашего вопроса, которые не включают в себя сохранение всех классов в одном пакете.

Во-первых, используйте шаблон Friend Accessor/Пакет друзей, описанный в (Практический дизайн API, Tulach 2008).

Вторым является использование OSGi. Здесь приведена статья объясняющая, как это делает OSGi.

Вопросы, относящиеся: 1, 2, 3 и 4.

Ответ 8

Вы можете делать такие магии с помощью специального загрузчика классов, но:

  • правильное разделение будет доступно только в проекте, укомплектованном вашим загрузчиком классов;
  • действительно сомнительно, что усилия по созданию такого загрузчика достойны.

В таких ситуациях я бы сделал что-то похожее на то, что мы можем видеть в стандартной Java. Например, вы видите javax.xml.stream.XMLInputFactory, но где-то у вас есть com.sun.xml.internal.stream.XMLInputFactoryImpl. Он отлично компилируется, если вы пишете:

new com.sun.xml.internal.stream.XMLInputFactoryImpl()

хотя вы вряд ли это сделаете:-) С системным свойством вы можете контролировать фактическую загружаемую реализацию. Для меня такой подход хорош во многих ситуациях.

Надеюсь, я правильно понял ваш вопрос;)

Ура!