Frage

Normalerweise erzeugt der Compiler Code Boxen und Unboxing auszuführen. Aber was hat den Compiler, wenn die Box-Werte werden nicht benötigt? Ist der (Oracle Standard) Compiler intelligent genug, um zu optimieren es weg?

Werfen Sie einen Blick auf diese Methode:

public static void requireInRange(int index, Object[] array) {
    if(index < 0 || index >= array.length)
        throw new IndexOutOfBoundsException();
}

Die einzige relevanten Informationen sind die array.length, so dass es sinnlos wäre, jeden Wert eines Arrays zum Beispiel boxen. Wie in diesem Code:

int[] anArray = {3, 4, 2};
requireInRange(3, anArray);

Wird der Compiler Insert Code tatsächlich für jeden Wert des Array-Boxen?

War es hilfreich?

Lösung

Es gibt kein Autoboxing in Ihrem Code. In der Tat gegeben:

public static void requireInRange(int index, Object[] array) {
   ...
}

int[] anArray = {3, 4, 2};
requireInRange(3, anArray); // DOES NOT COMPILE!!!

Während ein int kann zu einem Integer autoboxed werden, ein int[] tut nicht autoboxed zu Integer[] von Java bekommen. Sie können Bibliotheksfunktionen schreiben, dies zu tun, aber die Sprache wird diese Umwandlung nicht erleichtern.

Dies ist in der Tat die Quelle vieler Verwirrung in Bezug auf z.B. Arrays.asList(anIntArray) ist „gebrochen“, weil stattdessen ein List<Integer> zurückzukehren, was zurückgegeben wird, in der Tat ist ein Ein-Element List<int[]>.


Aber was ist die Leistung ???

Ein Zitat von Java Language Guide / Autoboxing

  

Es ist nicht zur Anwendung eines geeignete Autoboxing und für die wissenschaftliche Rechnen Unboxing oder anderen leistungsempfindlichen Zahlencode. Ein Integer ist kein Ersatz für eine int; Autoboxing und Unboxing verwischt die Unterscheidung zwischen primitiven Typen und Referenztypen, aber sie tun es nicht beseitigen.

Kurz gesagt, wann immer Autoboxing passiert, Leistung in Anspruch nimmt auf jeden Fall ein bisschen ein Hit. Bestimmte Dinge helfen, dies zu lindern, z.B. der Cache-Mechanismus in dieser Art gebaut. Dies ist, warum Sie die folgende bekommen:

    System.out.println(
        ((Integer) 0) == ((Integer) 0)
    );
    // true

    System.out.println(
        ((Integer) 10000) == ((Integer) 10000)
    );
    // false (implementation-specific)

Was ist hier passiert, ist, dass, wenn 0 ist automatisch geboxt, no neue Integer Instanz tatsächlich erstellt wird: Werte in bestimmten Bereich ist gecached für Autoboxing Zwecke, um die Leistung zu. 10000 in den meisten Umsetzung wahrscheinlich fällt dieser Bereich aus, aber einige JVM-Implementierungen tun können Sie den Cache-Bereich angeben, falls erforderlich.


Aber ich will nur die Länge des Arrays !!!

bekommen

Es gibt viele Möglichkeiten, um Ihre requireInRange zur Arbeit mit jeder Art von Arrays zu erleichtern. Leider bedeutet mal die Arbeit mit Java-Array von Primitiven oft viele Wiederholungen. Dieser Mittelwert Bereitstellung von Überlastungen für int[], boolean[], byte[], Object[] usw. getrennt.

Eine prägnante Option ist die Reflexion zu verwenden, aber das hat seine Vor- und Nachteile. Generell Reflexion nicht die bevorzugte Lösung für die meisten Szenarien sein sollte.

Having said that, java.lang.reflect.Array hat eine int getLength(Object array) static Methode, die die Länge von ANY Array. Es ist nicht typsicher (wie die meisten Reflexionsmechanismus sind); ein nicht-Array compiles vorbei, aber wirft IllegalArgumentException zur Laufzeit.

Verwandte Fragen

Andere Tipps

  

Wird der Compiler tatsächlich Insert Code   für jeden Wert der Array-Boxen?

Der Compiler den Code ablehnen, weil ein int[] nicht in eine Methode übergeben werden kann, die einen Object[] Parameter annimmt.

Autoboxing geschieht nur für einzelne primitive Werte, nie für ganzen Arrays.

Im Zweifelsfall können Sie den Compiler übernehmen optimiert den Code nicht. Im Allgemeinen es hat eine wörtliche Übersetzung des Codes.

Darüber hinaus, wenn im Zweifel youc eine der JVM übernehmen macht einen sehr guten Job, den Code zur Laufzeit zu optimieren. Ich würde nicht annehmen, dass es einen Unterschied macht, es sei denn Sie haben guten Grund (wie Profiler) zu vermuten, dass es ein Problem ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top