In diesem Artikel werden wir uns eine Funktion in Java namens Autoboxing/Unboxing ansehen . Autoboxing und Unboxing ist eine Funktion der Konvertierung primitiver Typen in Objekttypen und umgekehrt.
Der gesamte Prozess wird automatisch von der Java Runtime Environment (JRE) durchgeführt. Bei der Implementierung dieser Funktion ist jedoch Vorsicht geboten, denn... Dies kann die Leistung Ihres Programms beeinträchtigen.
Einführung
In Versionen vor JDK 1.5 war es nicht einfach, primitive Datentypen wie
int
,
char
, in ihre Wrapper-Klassen Integer, Character, Float, Double zu konvertieren. Ab JDK 5 wird diese Funktionalität, die Umwandlung primitiver Typen in äquivalente Objekte, automatisch implementiert.
Diese Eigenschaft wird als Autoboxing bezeichnet . Der umgekehrte Vorgang ist jeweils
das Unboxing , d.h. der Prozess der Konvertierung von Objekten in ihre entsprechenden primitiven Typen. Beispielcode für Autoboxing und Unboxing finden Sie unten:
Autoboxingfloat
double
Integer integer = 9;
Auspacken
int in = 0;
in = new Integer(9);
Wann kommt das automatische Ein- und Auspacken zum Einsatz? Autoboxing wird vom Java-Compiler unter den folgenden Bedingungen verwendet:
- Wenn ein Wert eines primitiven Typs als Methodenparameter an eine Methode übergeben wird, die ein Objekt der entsprechenden Wrapper-Klasse erwartet.
- Wenn ein Wert eines primitiven Typs einer Variablen der entsprechenden Wrapper-Klasse zugewiesen wird.
Betrachten Sie das folgende Beispiel:
Listing 1: Einfacher Code, der Autoboxing zeigt
public int sumEvenNumbers(List<Integer> intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}
Vor JDK 1.5 hätte der obige Code einen Kompilierungsfehler verursacht, da der Restoperator % und das unäre Plus += nicht auf eine Wrapper-Klasse angewendet werden konnten. Aber in JDK 1.5 und höher wird dieser Code fehlerfrei kompiliert und Integer in umgewandelt
int
. Unboxing wird vom Java-Compiler unter den folgenden Bedingungen verwendet:
- Wenn ein Objekt als Parameter an eine Methode übergeben wird, die einen entsprechenden primitiven Typ erwartet.
- Wenn ein Objekt einer Variablen des entsprechenden primitiven Typs zugewiesen wird.
Betrachten Sie das folgende Beispiel:
Listing 2: Einfacher Code, der das Auspacken zeigt
import java.util.ArrayList;
import java.util.List;
public class UnboxingCheck {
public static void main(String[] args) {
Integer in = new Integer(-8);
int absVal = absoluteValue(in);
System.out.println("absolute value of " + in + " = " + absVal);
List<Double> doubleList = new ArrayList<Double>();
doubleList.add(3.1416);
double phi = doubleList.get(0);
System.out.println("phi = " + phi);
}
public static int absoluteValue(int i) {
return (i < 0) ? -i : i;
}
}
Durch Autoboxing und Unboxing kann der Entwickler Code schreiben, der leicht zu lesen und zu verstehen ist. Die folgende Tabelle zeigt die primitiven Datentypen und ihre entsprechenden Wrapper-Objekte.
Primitive Typen |
Shell-Klassen |
Boolescher Wert |
Boolescher Wert |
Byte |
Byte |
verkohlen |
Charakter |
schweben |
Schweben |
int |
Ganze Zahl |
lang |
Lang |
kurz |
Kurz |
Tabelle 1: Primitive Typen und äquivalente Wrapper-Klassen mit Vergleichsoperatoren Autoboxing und Unboxing können mit Vergleichsoperatoren verwendet werden. Der folgende Codeausschnitt veranschaulicht, wie das geschieht:
Listing 3: Beispielcode, der Autoboxing und Unboxing mit einem Vergleichsoperator zeigt
public class BoxedComparator {
public static void main(String[] args) {
Integer in = new Integer(25);
if (in < 35)
System.out.println("Value of int = " + in);
}
}
Automatisches Packen und Entpacken beim Überladen einer Methode Das automatische Packen und Entpacken erfolgt beim Überladen einer Methode basierend auf den folgenden Regeln:
- In einer Situation, in der die Wahl zwischen Erweiterung und Verpackung besteht, „besiegt“ die Erweiterung die Verpackung; die Erweiterung ist vorzuziehen.
Listing 4: Beispielcode, der den Vorteil der Überladung zeigt
public class WideBoxed {
public class WideBoxed {
static void methodWide(int i) {
System.out.println("int");
}
static void methodWide( Integer i ) {
System.out.println("Integer");
}
public static void main(String[] args) {
short shVal = 25;
methodWide(shVal);
}
}
}
Programmausgabe - Typ
int
- Die Erweiterung übertrifft die variable Anzahl von Argumenten. In einer Situation, in der zwischen Erweiterung und variabler Anzahl von Argumenten gewählt werden muss, ist die Erweiterung vorzuziehen.
Listing 5: Beispielcode, der den Vorteil der Überladung zeigt
public class WideVarArgs {
static void methodWideVar(int i1, int i2) {
System.out.println("int int");
}
static void methodWideVar(Integer... i) {
System.out.println("Integers");
}
public static void main( String[] args) {
short shVal1 = 25;
short shVal2 = 35;
methodWideVar( shVal1, shVal2);
}
}
- Packen ist besser als eine variable Anzahl von Argumenten. In einer Situation, in der Sie zwischen Packen und einer variablen Anzahl von Argumenten wählen müssen, ist das Packen vorzuziehen.
Listing 6: Beispielcode, der den Vorteil der Überladung zeigt
public class BoxVarargs {
static void methodBoxVar(Integer in) {
System.out.println("Integer");
}
static void methodBoxVar(Integer... i) {
System.out.println("Integers");
}
public static void main(String[] args) {
int intVal1 = 25;
methodBoxVar(intVal1);
}
}
Bei der Verwendung von Auto Packing sollten Sie Folgendes beachten: Wie wir wissen, hat jede gute Funktion einen Nachteil. Autoverpackungen bilden in dieser Hinsicht keine Ausnahme. Einige wichtige Hinweise, die ein Entwickler bei der Verwendung dieser Funktion beachten sollte:
- Der Vergleich von Objekten mit dem
==
Operator „ “ kann verwirrend sein, da er auf primitive Typen und Objekte angewendet werden kann. Wenn dieser Operator auf Objekte angewendet wird, vergleicht er tatsächlich Verweise auf die Objekte und nicht auf die Objekte selbst.
Listing 7: Beispielcode, der den Vergleich zeigt.
public class Comparator {
public static void main(String[] args) {
Integer istInt = new Integer(1);
Integer secondInt = new Integer(1);
if (istInt == secondInt) {
System.out.println("both one are equal");
} else {
System.out.println("Both one are not equal");
}
}
}
- Mischen von Objekten und primitiven Typen mit den Gleichheits- und Vergleichsoperatoren. Wenn wir einen primitiven Typ mit einem Objekt vergleichen, ist das Objekt entpackt, was auslösen kann,
NullPointerException
wenn das Objekt null
.
- Objekt-Caching. Die Methode
valueOf()
erstellt einen Container mit primitiven Objekten, die sie zwischenspeichert. Da Werte im Bereich von -128 bis einschließlich 127 zwischengespeichert werden, verhalten sich diese zwischengespeicherten Objekte möglicherweise anders.
- Leistungsabfall. Autoboxing oder Unboxing beeinträchtigen die Anwendungsleistung, da dadurch ein unerwünschtes Objekt erstellt wird, das den Garbage Collector zu einer häufigeren Ausführung zwingt.
Nachteile von AutoBoxing Obwohl AutoBoxing eine Reihe von Vorteilen hat, hat es die folgenden Nachteile:
Listing 8: Beispielcode, der das Leistungsproblem zeigt.
public int sumEvenNumbers(List intList) {
int sum = 0;
for (Integer i : intList) {
if (i % 2 == 0) {
sum += i;
}
}
return sum;
}
In diesem Codeabschnitt
sum +=i
wird er erweitert auf
sum = sum + i
. Beginnend mit dem „
+
“-Operator beginnt die JVM mit dem Unboxing, da der „
+
“-Operator nicht auf ein Integer-Objekt angewendet werden kann. Und dann wird das Ergebnis automatisch zurückgepackt. Vor JDK 1.5 waren Datentypen
int
und Ganzzahlen unterschiedlich. Im Falle einer Methodenüberladung wurden diese beiden Typen problemlos verwendet. Mit der Einführung des automatischen Ein-/Auspackens ist dies schwieriger geworden. Ein Beispiel hierfür ist die überladene Methode
remove()
in
ArrayList
. Die Klasse
ArrayList
verfügt über zwei Löschmethoden –
remove(index)
und
remove(object)
. In diesem Fall kommt es nicht zu einer Methodenüberladung und die entsprechende Methode wird mit den entsprechenden Parametern aufgerufen.
Abschluss
Autoboxing ist ein Mechanismus zur impliziten Konvertierung primitiver Datentypen in entsprechende Wrapper-Klassen (Objekte). Der Compiler verwendet die Methode,
valueOf()
um primitive Typen in Objekte umzuwandeln, und die Methoden usw.
IntValue()
,
doubleValue()
um die primitiven Typen des Objekts zu erhalten. Autoboxing konvertiert den booleschen Typ
boolean
in einen booleschen Wert,
byte
in Byte,
char
in Zeichen,
float
in Float,
int
in Integer,
long
in Long
short
und in Short. Das Auspacken erfolgt in umgekehrter Richtung.
Originaler Artikel
GO TO FULL VERSION