Wie Array-Größe in Java-Bytecode (FindBugs) erfassen
-
13-09-2019 - |
Frage
Ich möchte über die Größe eines Arrays, um herauszufinden, indem man die Bytecode zugeordnet ist, wenn diese Informationen zum Zeitpunkt der Kompilierung bekannt ist, natürlich.
Hintergrund: Ich möchte einen FindBugs Detektor schreiben (was bei der kompilierten Bytecode aussieht) und bestimmte Vorkommen von Array Zuweisungen melden. Um Fehlalarme zu herauszufiltern ich in „kleinen“ Arrays nicht interessiert bin, sondern nur diejenigen, deren Größe bei der Kompilierung oder, die größer als eine konfigurierbare Schwelle nicht zur Verfügung.
Wie der FindBugs Sourcecode auch nicht schwer dokumentiert, ich suche für einige Hinweise, wie, um loszulegen - vielleicht bereits eine dectector ist, etwas zu tun ähnlich, dass ich aussehen könnte
.Lösung
Dies könnte etwas schwierig bekommen. Mein Wissen ist unvollständig, aber Sie werden mindestens drei Arten von Anweisungen haben, wo sie nach (newArray, ANEWARRAY und MULTIANEWARRAY). Mit Blick auf dem vorherigen Befehl (oder im Fall von MULTIANEWARRAY, n vorheriger Anleitung) erhält die Größe, das, selbst wenn es eine Konstante war vielleicht mit BIPUSH, SIPUSH oder LDC geladen wird (etwas anderes?), Je von der Größe. Wie Sie bemerkt haben, wenn die Klasse das Ergebnis einer Berechnung ist, können Sie Anweisungen zurück auf unbestimmte Zeit werden Tracing.
Wenn ich mich richtig erinnere, verwendet FindBugs die BCEL intern, aber ich habe gegraben nie um dort genau zu sehen, wie schlau sie sind. Wenn eine der beiden Teams entsprechende Mailinglisten haben, können sie einen besseren Platz beweisen fragen -. Sie werden wahrscheinlich zumindest wissen, ob jemand vor dieser Straße unten gewesen ist
Andere Tipps
Nun, wenn sie auf einer konstanten Basis zugeordnet sind, können Sie für eine konstante überprüfen, die kurz vor der Zuteilung geschoben wurde. Zum Beispiel:
class ArraySize {
private static final int smallsize = 10;
private static final int largesize = 1000;
public static void main(String[] args) {
int[] small = new int[smallsize];
int[] big = new int[largesize];
}
}
gibt den Bytecode:
Compiled from "ArraySize.java"
class ArraySize extends java.lang.Object{
ArraySize();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: bipush 10
2: newarray int
4: astore_1
5: sipush 1000
8: newarray int
10: astore_2
11: return
}