2013-02-25 11 views
6

Ist es möglich, eine letzte Klasse mit Bytecode-Manipulationen zu erben?Ist es irgendwie möglich, einen endgültigen klassenmodifizierenden Bytecode zu erben?

+1

Würde nicht "Komposition statt Vererbung" Ihr Problem lösen? Könnten Sie eine Wrapper-Klasse für das verwenden, was Sie tun möchten? Bitte posten Sie einige Details, es ist sehr schwierig, etwas zu beraten, wenn so wenig Informationen verfügbar sind ... (und vikingsteve hat Recht!) – ppeterka

+5

'final' ist normalerweise aus einem bestimmten Grund da ... – vikingsteve

+0

Welche Klasse versuchen Sie? geerbt von? Einer der Standardbibliotheken? –

Antwort

4

Ja und nein.

Sie können die Bytecode-Manipulation verwenden, um eine final-Klasse im laufenden Betrieb in eine Nicht-final-Klasse zu ändern. Dies beeinträchtigt nicht einmal die Binärkompatibilität, sodass keine Klassenlader/Verifier-Fehler auftreten.

Sie müssen jedoch die Bytecode-Änderungen an der Klasse final selbst anwenden. Sie können keine Bytecode-Manipulation an einer untergeordneten Klasse vornehmen, um sie von einer übergeordneten Klasse final zu erben. Oder genauer, wenn Sie das tun, wird die modifizierte Kindklasse vom Verifier zurückgewiesen, wenn sie zusammen mit der Elternklasse final geladen wird.

+0

Wenn Sie eine bestimmte Referenz haben wollen - JVMS Abschnitt 4.1, Seite 73 - "Weder die direkte Superklasse noch eine der Superklassen darf das ACC_FINAL-Flag im Attribut access_flags von seiner ClassFile-Struktur haben." – Antimony

+0

Die JLS erwähnt dies auch - http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.4.2 –

+0

Aber die Frage nach Bytecode-Manipulation, in welchem ​​Fall die JLS ist irrelevant. Die Java-Sprache hat viele willkürliche Einschränkungen, die auf der Bytecode-Ebene nicht vorhanden sind. – Antimony

0

This beschreibt das Klassendateiformat. Am Offset 10+cpsize gibt es 2 Bytes, die die Zugriffsflags dieser Klasse definieren. Eines dieser Flags heißt ACC_FINAL (0x0010). Ich nehme an, Sie können dieses Bit ausblenden und diese Klasse als nicht endgültig definieren.