JavaRush /Java-Blog /Random-DE /Autoboxing und Unboxing in Java
Viacheslav
Level 3

Autoboxing und Unboxing in Java

Veröffentlicht in der Gruppe Random-DE
<h2>Einführung</h2>Eine Programmiersprache lebt und verändert sich, genau wie die Sprache, die Menschen sprechen. In ihr tauchen neue Phänomene auf, um die Verwendung der Sprache komfortabler zu machen. Und wie wir wissen, sollte die Sprache unsere Gedanken bequem ausdrücken.
Autoboxing und Unboxing in Java - 1
Daher wurde in Java SE 5 der Boxing/Unboxing-Mechanismus eingeführt. Und ein eigenes Tutorial von Oracle ist den Funktionen dieses Mittels zum Ausdruck von Gedanken gewidmet: Autoboxing und Unboxing . <h2>Auto-Packing-Boxen</h2>Sehen wir uns ein Beispiel für Auto-Packing-Boxen an. Schauen wir uns zunächst an, wie es funktioniert. Lassen Sie uns die Website „compilejava.net“ verwenden und eine Klasse erstellen:
public class App {
    public static void main(String[] args) {
        Integer portNumber = 8080;
        if (args.length != 0) {
            portNumber = Integer.valueOf(args[0]);
        }
        System.out.println("Port number is: " + portNumber);
    }
}
Einfacher Code. Wir können den Eingabeparameter angeben und den Portwert ändern. Wie wir sehen, weil Wir lesen den Portwert aus Stringden Parametern und erhalten Integerihn, indem wir ihn durchleiten Integer.valueOf. Daher sind wir gezwungen, ihn nicht als primitiven Typ, sondern als Objekttyp anzugeben Integer. Und hier haben wir einerseits eine Objektvariable und der Standardwert ist ein Grundelement. Und es funktioniert. Aber wir glauben nicht an Magie, oder? Werfen wir einen Blick „unter die Haube“, wie man so schön sagt. Laden Sie den Quellcode von Compilejava.net herunter, indem Sie auf „ZIP herunterladen“ klicken. Extrahieren Sie anschließend das heruntergeladene Archiv in ein Verzeichnis und gehen Sie dorthin. Jetzt machen wir Folgendes: javap -c -p App.classDabei ist App.class die kompilierte Klassendatei für Ihre Klasse. Wir werden Inhalte wie diesen sehen:
Autoboxing und Unboxing in Java - 2
Dies ist derselbe berüchtigte „Bytecode“. Aber was uns jetzt wichtig ist, ist, was wir sehen. Zuerst wird das 8080-Grundelement auf dem Methodenausführungsstapel platziert und dann wird Integer.valueOf ausgeführt . Das ist die „Magie“ des Boxens. Und im Inneren sieht die Magie so aus:
Autoboxing und Unboxing in Java - 3
Das heißt im Wesentlichen, dass je nach Wert der Zahl eine neue Zahl entnommen Integeroder aus dem Cache abgerufen wird (der Cache ist nichts weiter als nur ein Array von Ganzzahlen). IntegerNatürlich Integerhatte nicht nur einer so viel Glück. Es gibt eine ganze Liste verwandter Grundtypen und ihrer Wrapper (Klassen, die Grundtypen in der OOP-Welt darstellen). Diese Liste finden Sie ganz unten im Tutorial von Oracle: „ Autoboxing und Unboxing “. Es ist sofort erwähnenswert, dass aus Grundelementen erstellte Arrays keinen „Wrapper“ haben, ohne dass Bibliotheken von Drittanbietern angeschlossen werden müssen. Diese. wird für uns nicht aus 's Arrays.asListmachen . <h2>Unboxing</h2>Der umgekehrte Vorgang zum Boxen wird Unboxing Unboxing genannt. Schauen wir uns ein Auspackbeispiel an: int[]ListInteger
public class App {

    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("Please, enter params");
            return;
        }
      	int value = Math.abs(Integer.valueOf(args[0]));
        System.out.println("Absolute value is: " + value);
    }

}
Math.absakzeptiert nur Grundelemente. Was zu tun? Die Wrapper-Klasse verfügt für diesen Fall über eine spezielle Methode, die ein Grundelement zurückgibt. Dies ist beispielsweise die intValue-Integer Methode . Wenn wir uns den Bytecode ansehen, sieht er so aus:
Autoboxing und Unboxing in Java - 4
Anscheinend gibt es keine Magie. Alles ist in Java. Es funktioniert einfach „von alleine“. Für unsere Bequemlichkeit. <h2>Rechen</h2>
Autoboxing und Unboxing in Java - 5
Jedes Werkzeug wird bei falscher Verwendung zu einer gefährlichen Waffe gegen sich selbst. Und der automatische Boxing/Unboxing-Mechanismus in Java bildet da keine Ausnahme. Der erste, offensichtliche Vergleich erfolgt durch ==. Ich denke, das ist klar, aber schauen wir es uns noch einmal an:
public static void main(String[] args) {
    Integer inCacheValue = 127;
    Integer inCacheValue2 = 127;
    Integer notInCache = 128; // new Integer(129)
    Integer notInCache2 = 128; // new Integer(129)
    System.out.println(inCacheValue == inCacheValue2); //true
    System.out.println(notInCache == notInCache2); //false
}
Im ersten Fall wird der Wert aus dem IntegerWertecache entnommen (siehe Erklärung zum Boxen oben), im zweiten Fall wird jedes Mal ein neues Objekt erstellt. Aber auch hier lohnt sich eine Reservierung. Dieses Verhalten hängt von der Cache-Obergrenze ( java.lang.Integer.IntegerCache.high ) ab. Darüber hinaus kann sich dieser Grenzwert aufgrund anderer Einstellungen ändern. Sie können die Diskussion zu diesem Thema auf Stackoverflow lesen: Wie groß ist der Integer-Cache? Natürlich müssen Objekte mit Gleichheit verglichen werden: System.out.println(notInCache.equals(notInCache2)); Das zweite Problem, das mit demselben Mechanismus verbunden ist, ist die Leistung. Jedes Boxen in Java entspricht dem Erstellen eines neuen Objekts. Wenn die Zahl nicht in den Cache-Werten enthalten ist (also -128 bis 127), wird jedes Mal ein neues Objekt erstellt. Wenn das Packen (d. h. Boxen) plötzlich in einer Schleife durchgeführt wird, führt dies zu einem enormen Anstieg unnötiger Objekte und einem Ressourcenverbrauch für die Arbeit des Garbage Collectors. Seien Sie deshalb nicht zu leichtsinnig. Ein dritter, nicht weniger schmerzhafter Rechen beruht auf demselben Mechanismus:
public static void check(Integer value) {
    if (value <= 0) {
        throw new IllegalStateException("Value is too small");
    }
}
In diesem Code versuchte die Person eindeutig, den Fehler nicht zu überwinden. Aber es gibt keinen Scheck dafür null. Wenn es um die Eingabe geht null, erhalten wir statt eines verständlichen Fehlers einen unverständlichen NullPointerException. Denn zum Vergleich: Java wird versuchen, auszuführen value.intValueund abzustürzen, weil ... valueWille null. <h2>Fazit</h2>Der Boxing/Unboxing-Mechanismus ermöglicht es dem Programmierer, weniger Code zu schreiben und manchmal nicht einmal an die Konvertierung von Grundelementen in Objekte und zurück zu denken. Das heißt aber nicht, dass Sie vergessen sollten, wie es funktioniert. Andernfalls kann es passieren, dass Ihnen ein Fehler unterläuft, der möglicherweise nicht sofort sichtbar wird. Wir sollten uns nicht auf Teile des Systems verlassen, die nicht vollständig unter unserer Kontrolle stehen (z. B. die Ganzzahlgrenze). Aber vergessen Sie nicht alle Vorteile von Wrapper-Klassen (wie Integer). Oft verfügen diese Wrapper-Klassen über eine Reihe zusätzlicher statischer Methoden, die Ihr Leben besser und Ihren Code ausdrucksvoller machen. Hier ist ein Nachholbeispiel:
public static void main(String[] args) {
    int first = 1;
    int second = 5;
    System.out.println(Integer.max(first, second));
    System.out.println(Character.toLowerCase('S'));
}
Die richtige Schlussfolgerung aus allem ist, dass es keine Magie gibt, sondern eine Art Erkenntnis. Und nicht immer wird alles so sein, wie wir es erwarten. Beispielsweise gibt es keine Verpackung: System.out.println("The number is " + 8); Das obige Beispiel wird vom Compiler in eine Zeile optimiert. Das heißt, es ist, als ob Sie „Die Zahl ist 8“ schreiben würden. Und im Beispiel unten wird es auch keine Verpackung geben:
public static void main(String[] args) {
    System.out.println("The number is " + Math.abs(-2));
}
Wie kann das sein, wenn wir printlnein Objekt als Eingabe nehmen und die Linien irgendwie verbinden müssen? Linien... ja, deshalb gibt es keine Verpackung als solche. Es Integergibt statische Methoden, aber einige davon sind package. Das heißt, wir können sie nicht nutzen, aber in Java selbst können sie aktiv genutzt werden. Genau das ist hier der Fall. Es wird die Methode getChars aufgerufen, die aus der Zahl ein Array von Zeichen erstellt. Auch hier keine Magie, nur Java). Man muss sich also in jeder unklaren Situation nur die Umsetzung ansehen, dann wird sich zumindest etwas ergeben. #Wjatscheslaw
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION