Fazit ist, ja, es ist machbar. Man kann den Namen einer inneren Klasse ändern, also ist sie kürzer als der ursprüngliche Name, der von javac
zugewiesen wurde.
Ich war auf der Suche durch The Java Language Specification und The Java Virtual Machine Specification zu finden, wo es über die Verwendung des $
Charakters spricht eine innere Klasse zu bezeichnen, und war nicht in der Lage einen Verweis darauf zu finden. Der Grund ist, es ist nicht wirklich wichtig.
Fall und Punkt:
class A {
class B {
class C {}
}
A() {
new B().new C();
}
public static void main(String[] s){
new A();
}
}
Hier haben wir innere Klassen verschachtelt. Wenn kompiliert, so erhalten wir die folgenden Dateien:
A.class
A$B.class
A$B$C.class
Hier ist ein schnelles Experiment ist:
- öffnen Sie die
A.class
-Datei, und ändern Sie sich auf ABCDE
den Verweis auf A$B$C
und ändern.
- Benennen Sie die
A$B$C.class
in ABCDE.class
um.
- Öffnen Sie die
ABCDE.class
, und ändern Sie den Verweis auf ABCDE
.
- Run
java A
, sehen, ob es läuft.
Hinweis: Der Grund für die A$B$C
-ABCDE
geändert wurde, ist, weil die Änderung in der Länge der Kennung des class
Dateiformat zu mangle scheint, und wird einen Fehler verursachen. Technische Erklärung wird am Ende dieses Beitrags sein.
Ergebnis? Es klappt.
Der Grund ist in der class
Datei. Hier ist eine Demontage der ursprünglichen A.class
, und nur die relevanten Teile:
Compiled from "A.java"
class A extends java.lang.Object
SourceFile: "A.java"
InnerClass:
#10= #3 of #7; //B=class A$B of class A
#22= #2 of #3; //C=class A$B$C of class A$B
// ... snip ... //
const #2 = class #21; // A$B$C
// ... snip ... //
const #21 = Asciz A$B$C;
// ... snip ...//
Es stellt sich heraus, der Name der inneren Klassen sind nur Namen in dem Konstanten-Pool.
Wenn der Name für die A$B$C
Klasse im konstanten Pool von A.class
zu ABCDE
geändert wird, und wenn der A$B$C
Klasse Dateiname und Name in der class
Datei geändert wird, dann wird die Java Virtual Machine wird mit der neu glücklich ausführen benannte innere Klasse.
Was bedeutet das?
Man muss nicht die MyClass$1$1$1 ... $1
für den Klassennamen verwenden, aber alles andere, was die eigenen Bedürfnisse erfüllen würde, daher wäre es möglich, mehr Kombinationen in einem kürzeren Dateinamen zu haben.
Wie würde jemand gehen und dies tun? Das werde ich dem Leser als Übung überlassen.
Hinweis auf die Verwendung von ABCDE
als neuen Klassennamen
In diesem Beitrag wird der Name der verschachtelten inneren Klasse wurde A$B$C
-ABCDE
geändert, um die Länge der Klasse zu halten, den gleichen Namen, in Um zu verhindern, dass ein ClassFormatError
geworfen wird. Der Grund dafür ist, dass die CONSTANT_Utf8_info
structure des Konstantenpools eine length
-Eigenschaft hat, die die Länge der Zeichenfolge angibt. Ich konnte die Länge nicht ändern, da ich die Datei class
in einem Texteditor bearbeitet habe.
Um die Zeichenfolge im konstanten Pool zu verkürzen, würde ich davon ausgehen, dass man den Wert des length
Feld verändern müsste sich die Länge der Zeichenfolge zu reflektieren.
aktualisieren
Ja, es ist möglich, die class
Datei Konstante Pool bearbeiten Sie den Namen der inneren Klasse zu verkürzen.
Ich war in der Lage, die ABCDE
Klasse in Z
Klasse zu ändern.
Hier ist ein Teil der Demontage des A.class
:
Compiled from "A.java"
class A extends java.lang.Object
SourceFile: "A.java"
InnerClass:
#10= #3 of #7; //B=class A$B of class A
#22= #2 of #3; //C=class Z of class A$B
// ... snip ...//
const #2 = class #21; // Z
// ... snip ...//
const #21 = Asciz Z;
// ... snip ...//
Wie jetzt genannt zu sehen ist, wird die innere Klasse von Z
, anstatt A$B$C
.
wurde die Änderung durch die Suche nach der Zeichenfolge A$B$C
in den A.class
und A$B$C.class
Dateien und ersetzt sie durch Z
, und das Ändern der Zeichen vor der Zeichenfolge aus dem Wert 0x05
-0x01
durchgeführt wird, bezeichnet, dass die Länge der Saite ist jetzt 1
statt 5
.
Mit diesen Änderungen, zusammen mit dem Umbenennen der Datei zu Z.class
, lief das Programm als ob nichts jemals passiert wäre.
Also ja, es ist möglich den Namen der inneren Klasse auch zu verkürzen.
Sie haben Klassen über 100 Ebenen tief verschachtelt ?! Heiliger Strohsack. :) – Bombe