1.參考變量

在 Java 語言中,有兩種​​變量:原始變量和其他變量。碰巧的是,我們現在要談談“其他一切”。

其實說有原始變量引用變量更正確。那麼這些參考變量是什麼?

與變量直接存儲值的原始類型不同,引用變量存儲對對象的引用。即內存某處有一個對象,引用變量只是存儲了這個對像在內存中的地址(對象的引用)。

只有基本類型將值直接存儲在變量中。所有其他類型只存儲一個對象引用。順便說一下,您已經遇到過兩種類型的變量——String變量和數組變量。

數組和字符串都是存儲在內存中某處的對象。String變量和數組變量僅存儲對對象的引用。

Java 中的引用變量

int a, int b and double d是將它們的值存儲在自身內部的原始變量。

變量String str是一個引用,將地址(引用)存儲到String內存中的對象。

將原始值分配給原始類型的變量時,其值被複製(複製)。分配引用變量時,僅複製對象的地址——不復制對象本身


2. 什麼是參考文獻?

參考變量和原始變量之間的根本區別是什麼?

原始變量就像一個盒子:您可以在其中存儲一些值。參考變量更像是一張上面有電話號碼的紙。

汽車 vs 汽車鑰匙

想像一下,您決定在朋友生日時送他一輛車。你不會把它包在一個盒子裡隨身攜帶:汽車太大了。

將車鑰匙放在一個足夠大的盒子裡會方便得多。當他從盒子裡拿出鑰匙時,你的朋友就會明白一切。當您只需交出鑰匙時,就無需隨身攜帶整輛車。

一個人 vs 她的電話號碼

或者這是另一個比較:一個人和她的電話號碼。一個電話號碼不是那個人,但是一個電話號碼可以用來給她打電話,向她詢問一些信息,或者提供指示。

類似地,引用用於與對象交互。所有對像都使用引用相互交互。我們不是“交換人”,而是簡單地交換電話號碼。

為原始變量賦值時,其值被複製(複製)。為引用變量賦值時,只會復制對象的地址(電話號碼)——不會復制對象本身。

引用提供了另一個優勢:您可以將對象引用傳遞給某個方法,該方法將能夠通過使用對對象的引用、調用對象的方法和訪問對象內部的數據來修改(更改)對象。


3.分配引用

分配引用變量時,只分配對像在內存中的地址。對象本身不會出現或消失。

這種方法避免了複製大量內存。如果您需要將一個非常大的對像傳遞給方法,我們只需傳遞對象引用即可。引用佔用的空間要少得多。

分配參考

所有引用變量(無論其類型如何)的大小都是相同的——4 個字節(類似於 int)。但!如果您的應用程序在 64 位 Java 機器上運行,那麼所有引用的大小都是 8 字節(64 位)。

更何況,引用只能相互賦值。您不能更改引用或為引用變量分配任意值:

代碼 描述
String hello = "Hello";
String s = hello;
這是允許的
String hello = "Hello";
hello++;
但這是不允許的
String hello = 0x1234;
這是不允許的

4.null參考

如果還沒有分配給它,引用變量存儲什麼?

它存儲引用。null是一個特殊的 Java 關鍵字,表示沒有引用(空引用)。該null值可以分配給任何引用變量。

所有引用變量都是,null除非它們已經分配了某種引用。

例子:

代碼 描述
class Person
{
   public static String name;
   public static int age;
}


String name變量有一個默認值:null
int age變量有一個默認值:0

對於原始類型和引用類型,未賦值的局部變量被視為未初始化。

如果一個變量存儲了對某個對象的引用,而您想清除該變量的值,則只需為其分配一個空引用即可。

代碼 描述
String s = null;
s = "Hello";
s = null;
s商店null。存儲對字符串對象存儲的
s引用。
snull

5.傳遞對方法的引用

如果方法的參數是引用類型,則值將以與處理非引用變量時相同的方式傳遞給該方法。該參數只是簡單地分配了另一個變量的值。

例子:

代碼 描述
class Solution
{
   public static void fill(String[] array, String value)
   {
      for (int i = 0; i < array.length; i++)
        array[i] = value;
   }

   public static void main(String[] args)
   {
     String[] data = new String[10];
     fill(data, "Hello");
   }
}


用傳遞的值 ( )填充fill傳遞的數組( )。arrayvalue

fill調用該方法時,array參數會被分配一個對數組的引用data。該value變量被分配了對字符串對象(“Hello”)的引用。

這是調用方法之前 內存的樣子fill

傳遞對方法的引用

這是方法運行 內存的樣子fill

傳遞對方法 2 的引用

和變量引用(存儲引用)內存中的同一容器dataarray

value變量存儲對字符串對象 ( ) 的引用"Hello"

數組的單元格也只存儲對"Hello"對象的引用。

事實上,沒有對像被複製——只有引用被複製。



6.與C/C++語言的比較

在面試中,有時會問 Java 程序員,Java 中數據是如何傳遞給方法的?有時問題是數據是按引用傳遞還是按值傳遞?

這個問題來自 C++,但在 Java 中意義不大。在 Java 中,參數總是簡單地分配參數的值。所以正確的答案是“按價值”。

但是請準備好解釋您的立場,因為您可能會立即聽到反駁:“原始類型按值傳遞,而引用類型按引用傳遞。”

這個問題的由來源於很多Java程序員過去都是C++程序員。在該編程語言中,如何將參數傳遞給方法的問題非常重要。

在 Java 中,一切都是明確的:原始類型存儲值,而引用類型也存儲一個值——一個引用。這是一個變量是否被認為是一個值的問題。

在 C++ 中,變量可以存儲對對象的引用和對象本身。原始類型也是如此:原始變量可以存儲一個值或將變量聲明為對int. 因此,為了避免混淆,C++ 程序員總是將引用的對象稱為引用對象本身稱為值。

在 C++ 中,您很容易遇到這樣的情況:一個變量包含一個對象,而另一個變量包含對該對象的引用。因此,變量存儲什麼的問題——對象本身或只是對它的引用——非常重要。當一個對像被傳遞給一個方法時,它被複製(如果通過值傳遞),而不是被複製(如果通過引用傳遞)。

在 Java 中,這種二元性不存在,所以正確答案是:arguments are passed to Java methods by value。只是當我們談論引用變量時,這個值是一個引用。