首頁 > Java > java教程 > 主體

Java 中的基本型別與引用以及字串的不變性

WBOY
發布: 2024-09-11 06:43:32
原創
206 人瀏覽過

在 Java 中,我們有兩種類型的資料(或變數):基元和非基元(也稱為引用)。

基本型別將其文字值儲存在堆疊、暫存和短期儲存記憶體中,由 Java 虛擬機 (JVM) 管理。 [在此閱讀有關記憶體類型的更多資訊]

原始變數分為四組:

1。整數類型: 用於儲存整數(不含小數部分)。它們是:byte、short、int、long。 Long 在數字末尾帶有字母“L”或“l”,用於區分。

2。浮點數類型::用於儲存帶有小數部分的數字(實數)。它們是:浮動、雙精度。浮點數的數字末尾帶有字母“F”或“f”,用於區分。

3。字元類型: 用於儲存單一字元(如字母、數字或符號):char。它們用單引號 '' 初始化,而不是雙引號 ""。

4。布林類型: 用於儲存邏輯值(true 或 false):bool

請參考下表,以了解每種類型的值範圍以及「預設」值:

Tipos primitivos vs referências em Java e a imutabilidade das Strings
在科學格式中,E 代表指數。例如,1.23E+10 等於 1.23 x 10^10

什麼是預設值?這是變數在未初始化的情況下將採用的值。然而,要假設這個值,它必須是全局的或恆定的(最終的)。

public final boolean isTrue;
登入後複製

在這行程式碼中,變數「isTrue」沒有被初始化,但是編譯器不會報錯,因為它會考慮布林變數的預設值「false」。

這裡,一個重要的警告:如果變數的作用域是局部的,也就是說,如果它已經在函數內聲明,我們程式設計師將被迫為其賦值。否則會出現編譯錯誤。

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

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

        System.out.println(j);
    }
登入後複製

在這個例子中,即使我們知道“2 < 10”返回“true”,編譯器在其過程中從不執行它翻譯的程式碼,不知道條件為真,也不知道原始變數“j”將始終被初始化。這樣,當嘗試執行程式碼時,就會出現編譯錯誤:「錯誤:變數 j 可能尚未初始化」。

記憶體位址

Java 中的第二種資料型別稱為 引用。這些變數儲存引用,即物件的記憶體位址,而不是像原始類型那樣直接儲存其值。此儲存發生在堆記憶體中。

一般來說,引用類型是類別、介面、枚舉和物件。

這裡是一個附錄。我們在程式碼中廣泛使用的 String 是一個類,而不是原始類型。請注意,即使是名稱也是大寫的,這是 Java 中類別的命名約定。

String 甚至還有一些方法,例如length(),它傳回儲存在其中的文字的大小,charAt(int index),它傳回文字中字元的索引,或substring(int beginIndex, int endIndex),它傳回一段字串。

但是,如果您希望更輕鬆地操作原始數據,Java 也允許這樣做。為此,它有 Wrapper 類,它已經附帶了一系列內建方法來處理基本類型。

包裝器基本上與原始變數具有相同的名稱,但是第一個字母大寫:

  • 位元組到位元組
  • 短褲短褲
  • 整數到 int
  • 長來長
  • 浮來浮去
  • 雙倍到雙倍
  • 字符到字符
  • 布林值到布林值
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);
        }
    }
}
登入後複製

在此範例程式碼中,int 包裝器用於將字串轉換為數字 (Integer.parse),然後將其與另一個數字進行比較 (Integer.compare)。

然而,String 有一個其他類別所沒有的特殊性。她是一成不變的。

讓我們透過這個基本範例來反思:

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   
  }

}
登入後複製

在這種情況下,請注意,即使字串“text2”指向“text1”,“text2”中的更改也不會反映“text1”中的更改。現在,當指向「test1」的物件「test2」的屬性發生變更時,此變更也會反映在「test1」中。

ねえ、でも参照変数にはリテラル値ではなくメモリ アドレスが格納されるのではありませんか?はい、保管しています。何が起こるかというと、Java 言語開発者は String 変数を不変のままにする決定を下したということです。これは、String オブジェクトの値を一度定義すると、別のオブジェクトによって間接的に変更できないことを意味します。

したがって、この例では、text1 が以前に参照したオブジェクトの値を変更しません (String は不変であるため)。代わりに、値「Weird」を持つ新しい String オブジェクトを作成し、text1 がこの新しいオブジェクトを指すようにします。 Text2 は引き続き元の "Hello" オブジェクトを指すため、値 "Hello" が保持されます。

つまり、文字列に新しい値を代入しても、既存のオブジェクトの値は変更されず、新しいオブジェクトへの参照が変更されるだけです。

TestClass などのカスタム クラスのオブジェクトは変更可能です。 test1 参照と test2 参照はどちらも同じオブジェクトを指しているため、一方の状態を変更すると他方にも反映されます。

以上是Java 中的基本型別與引用以及字串的不變性的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!