Java ist eine stark typisierte Sprache, es ist jedoch dennoch möglich, Werte zwischen primitiven Variablen unterschiedlichen Typs zu übertragen. Beispielsweise kann ich den Wert eines int problemlos einem Double zuweisen, solange die Speicherkapazität des Typs, der den Wert empfängt, damit zurechtkommt.
Sehen Sie unten die Größe jedes Grundtyps:
Die Übertragung von Werten auf einen Typ mit größerer Speicherkapazität hat einen technischen Namen: „Erweiternde Konvertierung“. Der Begriff wird im Portugiesischen üblicherweise mit „Erweiterungsumwandlung“ oder „Erweiterungsumwandlung“ übersetzt. Es bezieht sich auf den Prozess, bei dem ein Wert von einem kleineren oder eingeschränkteren Datentyp ohne Informationsverlust in einen größeren oder umfassenderen Typ konvertiert wird.
Aber was ist, wenn ich den Wert auf einen Typ mit weniger Speicherkapazität übertragen möchte? Dem Java-Compiler gefällt das nicht, aber er lässt es zu, wenn Sie es umwandeln, wie im Beispiel unten.
double decimal = 65.9; int i = (int) decimal; //aqui ele perde a casa decimal e vira 65 char c = (char) i; //aqui ele vira a letra A (que corresponde a 65)
Wenn die Größe des Werts, der an den neuen Typ übertragen wird, die Grenzen dieses Typs überschreitet, kann etwas Dramatischeres passieren. Ein int i = 10 passt in eine Byte-Variable, da er 8 Bits in einem Bereich von -128 bis 127 enthält. Was aber, wenn ich einen int i = 128 in eine Variable vom Typ Byte einfügen möchte ... wird es geben ein Informationsverlust .
public class Main { public static void main(String[] args) { int i = 128; byte b = (byte) i; System.out.println(b); // o valor de b agora é -128 :S } }
Im letzten Beitrag [hier lesen] habe ich ein wenig über die Wrapper-Klassen gesprochen. Als Beispiel hatte ich Integer.parse(i) = Imagine that i is a type
geschrieben
primitives int.
Derzeit wird die Verwendung der Wrapper-Parse-Methode nicht mehr empfohlen, da sie veraltet ist. Um ein Grundelement in eine Wrapper-Klasse umzuwandeln und auf diese Weise integrierte Methoden zu verwenden, wird empfohlen, „Autoboxing“ durchzuführen, wie im Beispiel:
Character ch = 'a'; Integer i = 10;
Beachten Sie, dass dies ein direkterer Ansatz ist. Sie weisen den Wert einfach auf einmal zu.
Um das Gegenteil zu tun und die Daten als primitiven Typ zurückzugeben, können Sie das „Unboxing“ mit der Methode valueOf:
durchführen
Integer i = 10; int j = Integer.valueOf(i);
Den Wrapper aus einem Grundelement zu machen, wie ich im vorherigen Beitrag sagte, hat den Vorteil, dass Sie die Methoden der Klasse verwenden können und die Arbeit mit den Daten einfacher wird.
Die Wrapper-Version eines Grundelements sieht auf den ersten Blick vielleicht sehr ähnlich aus, aber die JVM behandelt ein Objekt und ein Grundelement nicht auf die gleiche Weise, vergessen Sie das nicht. Denken Sie daran, dass Primitive auf den Stack und Objekte auf den Heap gehen [hier erinnern].
In Bezug auf die Leistung ist klar, dass das Abrufen von Daten aus einem Grundelement für den Computer weniger kostspielig ist, da der Wert direkt und nicht per Referenz gespeichert wird. Es ist viel schneller, vorgefertigte Daten zu erhalten, als die einzelnen Teile ständig im Speicher zusammenzusetzen.
Aber es gibt Fälle, in denen die Verwendung eines Wrappers unerlässlich ist. Zum Beispiel, wenn Sie mit der ArrayList-Klasse arbeiten möchten. Es akzeptiert nur Objekte als Parameter, keine Grundwerte.
Die Flexibilität, die diese Transformation vom Primitiv zum Objekt und umgekehrt mit sich bringt, ist wirklich cool an der Sprache. Aber wir müssen uns dieser und vieler anderer Fallstricke bewusst sein, die hier besprochen werden.
Um die Gesellschaft zu schockieren (lol), werde ich ein Beispiel für einen problematischen Fall geben, bei dem es um das unerwartete Verhalten eines Codes bei der Arbeit mit Überladung geht (ich habe noch keinen Beitrag zum Thema Überladung verfasst, werde es aber tun. Grundsätzlich tritt eine Überladung auf, wenn eine Methode unterschiedliche Signaturen hat.
Dieser Fall wurde im Buch „Effective Java“ von Joshua Bloch erwähnt.
public class SetListTest { public static void main(String[] args) { Setset = new TreeSet(); List list = new ArrayList(); for (int i = -3; i In diesem Programm bestand das Ziel darin, ganzzahlige Werte von -3 bis 2 [-3, -2, -1, 0, 1, 2] zu einer Menge und einer Liste hinzuzufügen. Dann löschen Sie die positiven Werte [0, 1 und 2]. Wenn Sie diesen Code jedoch ausführen, werden Sie feststellen, dass die Menge und die Liste nicht das gleiche Ergebnis lieferten. Die Menge gibt erwartungsgemäß [-3, -2, -1] zurück. Liste gibt [-2, 0, 2] zurück.
Dies geschieht, weil der Aufruf der integrierten Methode „remove(i)“ der List-Klasse i als einen primitiven Typ int und nichts anderes behandelt. Die Methode wiederum entfernt Elemente an Position i.
Der Aufruf der Methode „remove(i)“ der Set-Klasse ruft eine Überladung auf, die ein Integer-Objekt als Parameter empfängt und i, das ursprünglich ein int war, automatisch in „Integer“ konvertiert. Das Verhalten dieser Methode schließt wiederum Elemente aus der Menge aus, die einen Wert gleich i (und keinen Index gleich i) haben – beachten Sie, dass der erwartete Typ sowohl für die Menge als auch für die Liste Integer war. (Set-Set / Listenliste). Aus diesem Grund wurde die für die Remove-Methode der Set-Klasse gewählte Überladung in Integer konvertiert.
Während das Verhalten von „remove“ in „List“ darin besteht, nach Index zu löschen, besteht „remove“ in „Set“ darin, nach Wert zu löschen. Alles aufgrund der Überlastung von Remove, das Integer empfängt.
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3