Heim  >  Artikel  >  Java  >  Primitive Typen vs. Referenzen in Java und die Unveränderlichkeit von Strings

Primitive Typen vs. Referenzen in Java und die Unveränderlichkeit von Strings

WBOY
WBOYOriginal
2024-09-11 06:43:32209Durchsuche

In Java gibt es zwei Arten von Daten (oder Variablen): Primitive und Nicht-Primitive (auch Referenzen genannt).

Die primitiven Typen haben ihre Literalwerte im Stack gespeichert, einem temporären und kurzfristigen Speicher, der von der Java Virtual Machine (JVM) verwaltet wird. [Lesen Sie hier mehr über Speichertypen]

Primitive Variablen werden in vier Gruppen unterteilt:

1. Ganzzahltypen: werden zum Speichern von Ganzzahlen (ohne Dezimalteil) verwendet. Sie sind: Byte, Short, Int, Long. Das Long hat zur Unterscheidung den Buchstaben „L“ oder „l“ am Ende der Zahl.

2. Gleitkommatypen:: Wird zum Speichern von Zahlen mit Dezimalteil (reelle Zahlen) verwendet. Sie sind: float, double. Der Float hat zur Unterscheidung den Buchstaben „F“ oder „f“ am Ende der Zahl.

3. Zeichentyp: Wird zum Speichern einzelner Zeichen (z. B. Buchstaben, Ziffern oder Symbole) verwendet: char. Sie werden mit einfachen Anführungszeichen '' anstelle von doppelten "" initialisiert.

4. Boolescher Typ: Wird zum Speichern logischer Werte (wahr oder falsch) verwendet: bool

In der folgenden Tabelle finden Sie den Wertebereich, den jeder Typ zusätzlich zu seinen „Standard“-Werten hat:

Tipos primitivos vs referências em Java e a imutabilidade das Strings
Im wissenschaftlichen Format stellt E einen Exponenten dar. Beispielsweise entspricht 1,23E+10 1,23 x 10^10

Was ist ein Standardwert? Dies ist der Wert, den die Variable annimmt, wenn sie nicht initialisiert wurde. Um diesen Wert anzunehmen, muss er jedoch global oder konstant (endgültig) sein.

public final boolean isTrue;

In dieser Codezeile wurde die Variable „isTrue“ nicht initialisiert, aber der Compiler zeigt keinen Fehler an, da er den Standardwert „false“ für die boolesche Variable berücksichtigt.

Hier eine wichtige Warnung: Wenn der Gültigkeitsbereich der Variablen lokal ist, das heißt, wenn sie innerhalb einer Funktion deklariert wurde, sind wir Programmierer gezwungen, ihr einen Wert zuzuweisen. Andernfalls tritt ein Kompilierungsfehler auf.

public void teste(){
        int i = 2;
        int j;

        if (i < 10){
            j = 5;
        }

        System.out.println(j);
    }

Obwohl wir in diesem Beispiel wissen, dass „2 < 10“ „wahr“ zurückgibt, weiß der Compiler, der die Codes, die er während seines Prozesses übersetzt, niemals ausführt, nicht, dass die Bedingung wahr ist und dass die primitive Variable „j“ wird immer initialisiert. Auf diese Weise wird beim Versuch, den Code auszuführen, ein Kompilierungsfehler angezeigt: „Fehler: Variable j wurde möglicherweise nicht initialisiert“.

Speicheradressen

Der zweite Datentyp in Java heißt Referenz. Diese Variablen speichern eine Referenz, also die Speicheradresse eines Objekts, anstatt seinen Wert direkt zu speichern, wie es bei primitiven Typen der Fall ist. Diese Speicherung erfolgt im Heap-Speicher.

Referenztypen sind im Allgemeinen Klassen, Schnittstellen, Aufzählungen und Objekte.

Hier ein Nachtrag. Der String, den wir häufig in unseren Codes verwenden, ist eine Klasse und kein primitiver Typ. Beachten Sie, dass sogar der Name großgeschrieben wird, ebenso wie die Namenskonvention für Klassen in Java.

Der String verfügt sogar über Methoden wie length(), die die Größe des darin gespeicherten Textes zurückgibt, charAt(int index), die den Index eines Zeichens im Text zurückgibt, oder substring(int beginIndex, int endIndex), der einen Teil einer Zeichenfolge zurückgibt.

Aber wenn Sie die Bearbeitung primitiver Daten einfacher machen möchten, ermöglicht Java dies auch. Dafür gibt es die Wrapper-Klasse, die bereits über eine Reihe integrierter Methoden für die Arbeit mit den Grundtypen verfügt.

Wrapper haben grundsätzlich den gleichen Namen wie die primitive Variable, allerdings mit großgeschriebenem Anfangsbuchstaben:

  • Byte für Byte
  • Shorts für Shorts
  • Ganzzahl zu int
  • Lang bis lang
  • Float to float
  • Verdoppeln, um sich zu verdoppeln
  • Zeichen zum Zeichen
  • Boolescher Wert zu Boolescher Wert
public class WrapperExample {
    public static void main(String[] args) {
        String numeroStr = "123";
        Integer num1 = Integer.parseInt(numeroStr);
        Integer num2 = 200;

        int resultadoComparacao = Integer.compare(num1, num2);

        if (resultadoComparacao < 0) {
            System.out.println(num1 + " é menor que " + num2);
        } else if (resultadoComparacao > 0) {
            System.out.println(num1 + " é maior que " + num2);
        } else {
            System.out.println(num1 + " é igual a " + num2);
        }
    }
}

In diesem Beispielcode wird der int-Wrapper verwendet, um eine Zeichenfolge in eine Zahl (Integer.parse) umzuwandeln und sie dann mit einer anderen Zahl (Integer.compare) zu vergleichen.

String hat jedoch eine Besonderheit, die andere Klassen nicht haben. Sie ist unveränderlich.

Lassen Sie uns anhand dieses einfachen Beispiels nachdenken:

public class Main {
  public static void main(String[] args) {

    String text1 = "Hello";
    String text2 = text1;

    System.out.println(text1); //output: Hello
    System.out.println(text2); //output: Hello

    text1 = "Weird";
    System.out.println(text1); //output: Weird
    System.out.println(text2); //output: Hello

    text2 = "World";
    System.out.println(text1); //output: Weird
    System.out.println(text2); //output: World

    TestClass test1 = new TestClass("propertyValue");
    TestClass test2 = test1;

    System.out.println(test1.getProperty()); //output: propertyValue
    System.out.println(test2.getProperty()); //output: propertyValue

    test2.setProperty("newValue");

    System.out.println(test1.getProperty()); //output: newValue
    System.out.println(test2.getProperty()); //output: newValue   
  }

}

Beachten Sie in diesem Fall, dass Änderungen in „text2“ keine Änderungen in „text1“ widerspiegeln, obwohl der String „text2“ auf „text1“ verweist. Wenn nun beim Objekt „test2“, das auf „test1“ zeigte, eine Eigenschaft geändert wurde, spiegelte sich diese Änderung auch in „test1“ wider.

Hey, aber speichern Referenzvariablen nicht Speicheradressen anstelle von Literalwerten? Ja. Sie speichern es. Was passiert ist, dass die Java-Sprachentwickler die Entscheidung getroffen haben, String-Variablen unveränderlich zu lassen. Dies bedeutet, dass der Wert eines String-Objekts nach seiner Definition nicht indirekt durch ein anderes Objekt geändert werden kann.

Im Beispiel ändern wir daher nicht den Wert des Objekts, auf das text1 zuvor verwiesen hat (da String unveränderlich ist). Stattdessen erstellen wir ein neues String-Objekt mit dem Wert „Weird“ und lassen text1 auf dieses neue Objekt verweisen. Text2 zeigt weiterhin auf das ursprüngliche „Hello“-Objekt und behält daher den Wert „Hello“ bei.

Kurz gesagt, das Zuweisen eines neuen Werts zu einer Zeichenfolge ändert nicht den Wert des vorhandenen Objekts, sondern lediglich den Verweis auf ein neues Objekt.

Objekte benutzerdefinierter Klassen, wie z. B. TestClass, sind veränderbar. Sowohl test1- als auch test2-Referenzen verweisen auf dasselbe Objekt, sodass sich die Änderung des Status eines von ihnen auf das andere auswirkt.

Das obige ist der detaillierte Inhalt vonPrimitive Typen vs. Referenzen in Java und die Unveränderlichkeit von Strings. 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