Heim  >  Artikel  >  Java  >  Vorsicht bei der Typübertragung in Java

Vorsicht bei der Typübertragung in Java

王林
王林Original
2024-09-12 10:16:50737Durchsuche

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:

Cuidados com transferência de tipos em Java

Das Übertragen 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.

Was aber, wenn ich den Wert auf einen Typ mit geringerer 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 dem neuen Typ zugewiesen wird, die Grenzen dieses Typs überschreitet, kann etwas Dramatischeres passieren. Ein int i = 10 passt in eine Bytevariable, da es 8 Bits in einem Bereich von -128 bis +127 enthält. Was aber, wenn ich ein int i = 128 in eine Variable vom Typ Byte einfügen möchte ... es kommt zu einem 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
    }
}

Autoboxen

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 es sich um einen direkteren Ansatz handelt. Weisen Sie den Wert einfach auf einmal zu.

Um das Gegenteil zu erreichen 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);

Das Erstellen eines Wrappers aus einem Grundelement hat, wie ich im vorherigen Beitrag sagte, 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, ein fertiges Datenstück zu erhalten, als die 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.

Nur ​​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. Im Grunde genommen , Überladung tritt 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) {
        Set<Integer> set = new TreeSet<>();
        List<Integer> list = new ArrayList<>();

        for (int i = -3; i < 3; i++) {
            set.add(i);
            list.add(i);
        }

        for (int i = 0; i < 3; i++) {
            set.remove(i);
            list.remove(i); // como corrigir: list.remove((Integer) i);
        }

        System.out.println(set + " " + list);

    }

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 automatisch i, das ursprünglich ein int war, 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 gewählte Überladung aus der Set-Klasse 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.

Das obige ist der detaillierte Inhalt vonVorsicht bei der Typübertragung in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn