Если вы хотите основать поведение на интерфейсе, вы можете использовать статический инициализатор в этом интерфейсе.
public interface Foo{
static{
// do initializing here
}
}
Я не говорю, что это хорошая практика, но она определенно инициализируется при первой загрузке одного из реализующих классов.
Обновление: статические блоки в интерфейсах недопустимы. Вместо этого используйте абстрактные классы!
Справка:
Но если я вас правильно понял, вы хотите, чтобы инициализация происходила один раз для каждого реализующего класса. Это будет сложно. Вы определенно не можете сделать это с помощью решения на основе интерфейса. Вы можете сделать это с помощью абстрактного базового класса, который имеет динамический инициализатор (или конструктор), который проверяет, существует ли уже запрошенное отображение, и добавляет его, если его нет, но делать такие вещи в конструкторах - это просто хак.
Я бы сказал, что самые чистые варианты: либо генерировать код во время сборки (с помощью обработки аннотаций с помощью apt, либо с помощью анализа байт-кода с помощью такого инструмента, как asm), либо использовать агент во время загрузки класса для динамического создания отображения.
Ах, больше ввода. Отлично. Поэтому клиенты используют вашу библиотеку и предоставляют сопоставления на основе аннотаций. Тогда я бы сказал, что ваша библиотека должна предоставить метод инициализатора, где клиентский код может регистрировать классы. Примерно так:
YourLibrary.getInstance().registerMappedClasses(
CustomClass1.class,
CustomClass2.class,
CustomClass3.class,
CustomClass4.class
)
Или, что еще лучше, механизм сканирования пакетов (пример кода для реализации этого можно найти по этому вопросу ):
YourLibrary.getInstance().registerMappedClassesFromPackages(
"com.mycompany.myclientcode.abc",
"com.mycompany.myclientcode.def"
)
В любом случае, в принципе, нет способа избежать того, чтобы ваши клиенты выполняли такую работу, потому что вы не можете контролировать ни их процесс сборки, ни загрузчик классов для них (но вы, конечно, могли бы предоставить руководства для загрузчика классов или конфигурации сборки).