2015-05-15 2 views
7

Мне интересно, можно ли сгенерировать класс через обработчик аннотации, который будет внутренним классом компилируемого класса.Возможно ли создать внутренний класс класса для компиляции с помощью обработчика аннотаций?

Например, при компиляции класса A сгенерировать класс A$Foo. Интересно, есть ли трюк, который можно использовать или нет. У меня возникло ощущение, что возможно создать некоторый источник, который будет скомпилирован в том же байтовом коде, что и внутренний класс. И при компиляции/времени выполнения JVM возьмет его для внутреннего класса и разрешит доступ к закрытым полям внешнего класса.

Идея этого вопроса, который не является вопросом noobie, хотя он может выглядеть более или менее техническим, заключается в использовании частного модификатора видимости для аннотированных полей, таких как Dagger, ButterKnife и т. Д. Частный модификатор, позволяющий для более удобного обнаружения неиспользуемых полей, в то время как частная защита пакетов скрывает их.

Или есть ли какое-либо обходное решение, любой способ получить лучшее из обоих слов?

+1

Нет. Вы не можете изменить существующие исходные файлы, просто создайте новые. Но я всегда называю сгенерированные классы в соответствии с этой схемой, например 'SomeInterface $ Impl', чтобы указать, что этот сгенерированный класс принадлежит' SomeInterface'. –

+1

Но я точно знаю, что вы имеете в виду, я много общаюсь с обработкой аннотаций и много использую его в своих библиотеках, и я просто хочу, чтобы это было возможно .... Обычно я обычно генерирую частные конечные классы реализации, а затем генерирую public factory class, который создает экземпляры этих интерфейсов с частными классами реализации. Вы можете называть это обходным путем. –

ответ

-2

Личная видимость - это действительно просто подсказка для компилятора. Нет никакой проблемы с доступом к этим полям во время выполнения вообще (например, я делаю это в своей маленькой инжекционной зависимости: https://github.com/ko5tik/andject)

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

Во время компиляции вы можете использовать инструмент генерации исходного кода, например xdoclet (хотя он стал технически устаревшим много лет назад, но все же иногда используется) и генерировать все источники, которые вам нужны заранее, прежде чем компилировать их.

+2

В библиотеке, на которую вы ссылаетесь, вы используете отражение для выполнения инъекции. В большинстве случаев это именно то, чего вы хотите избежать при использовании обработки аннотаций и генерации кода. И код, который вы генерируете, должен быть действительным кодом, а действительный код не может получить доступ к закрытым полям. –

+1

Частная видимость не «* просто подсказка для компилятора *». В случае по умолчанию вы можете получить доступ к закрытым полям с отражением, но это может быть отключено, если ваш код работает в контексте с другим менеджером безопасности. В этом случае 'Field.setAccessible' выдает' SecurityException'. – Lii

2

Учитывая ваш прецедент, нет.

Внутренний класс является нормальным классом Java, живущим в другом файле .class. При компиляции в конструктор внутреннего класса добавляется скрытый параметр конструктора. Частные поля во внешнем классе становятся доступными путем добавления скрытых методов доступа во внешнем классе. Все это происходит во время компиляции.

JVM не имеет к этому никакого отношения. Если вы создаете класс, который «выглядит как внутренний класс другого класса», это не сделает доступными поля внешнего класса.

+0

Это общая идея, которую я имею в ограничении. Фактически добавление нескольких javap-c дампов внутреннего и внешнего классов помогло бы рассмотреть этот ответ каноническим. – Snicolas

+0

Кроме того, это справедливо только для компилятора javac, ecj AFAIK имеет другой механизм для выражения связи между внешним и внутренним классами. – Snicolas

Смежные вопросы