Возможно ли наследовать конечный класс, используя манипуляции с байт-кодом?Можно ли как-то наследовать последний класс, изменяющий байт-код?
ответ
Да и нет.
Вы можете использовать манипуляции с байт-кодом, чтобы изменить класс final
на final
на лету. Это даже не нарушает двоичную совместимость, поэтому нет риска ошибок загрузчика/верификации класса.
Однако вы должны применить модификации байт-кода к самому классу final
. Вы не можете манипулировать байт-кодом в дочернем классе, чтобы наследовать его от родительского класса final
. Точнее, если вы сделаете это, модифицированный дочерний класс будет отклонен верификатором при загрузке вместе с родительским классом final
.
Если вы хотите получить конкретную ссылку - раздел 4.1 JVMS, стр. 73 - «Ни один из прямых суперклассов, ни любой из его суперклассов могут иметь флаг ACC_FINAL, установленный в элементе access_flags его структуры ClassFile». – Antimony
JLS также упоминает об этом - http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.2 –
Но вопрос задан об обработке байт-кода, и в этом случае JLS не имеет значения. Язык Java имеет множество произвольных ограничений, которые отсутствуют на уровне байт-кода. – Antimony
This описывает формат файла класса. На смещении 10+cpsize
существует 2 байта, определяющих флаги доступа этого класса. Один из этих флагов называется ACC_FINAL (0x0010). Я полагаю, вы можете замаскировать этот бит и сделать этот класс не финальным.
Не будет ли «композиция вместо наследования» решить вашу проблему? Не могли бы вы использовать класс-оболочку для того, что вы пытаетесь сделать? Пожалуйста, разместите некоторые детали, очень сложно что-то посоветовать, если будет доступно небольшое количество информации ... (и vikingsteve прав!) – ppeterka
'final' обычно есть по какой-то причине ... – vikingsteve
В каком классе вы пытаетесь наследовать? Один из стандартных библиотечных? –