1. 程式人生 > >java中,引用物件時常遇到的問題

java中,引用物件時常遇到的問題

在Java中,常常遇到一些問題,如建立物件時,直接 宣告一個物件(String data;),new 出一個物件(String data = new String(“a”);) 和 直接“= null”(String data = null;) 或者”String data = “a”; “這三種建立方式各自是什麼意思,有什麼作用,有什麼區別,使用時會產生什麼樣的後果?為了搞清楚這四個方面的問題,蒐集整理了一些相關知識,簡單概括如下:

一、java建立物件時,new 出一個物件 和 = null的區別:
“ModelInfo model=null; model = h.getInfo(); 與 ModelInfo modelInfo = new ModelInfo()”
java裡物件傳遞的時候,傳遞的都是引用(也就是物件的地址),這比傳遞整個物件高效的多。而基礎型別,int,double等傳遞的才是值。
比如,(new ArrayList).add(new String(“hello”)),jvm只是把new String(“hello”)的地址存入到了列表list裡面。String str = new String(“Test”),是開闢記憶體放入了物件,並把它的引用賦給str。
String a = null; 和 String a = new String(); 後者例項化了物件,而null沒有,
然而“ModelInfo model=null 與 ModelInfo modelInfo=new ModelInfo()”: 前者是聲明瞭一個物件的引用,jvm並沒有開闢記憶體放入一個物件;後者在聲明瞭一個物件的引用之後,又把新開闢的沒有儲存任何有效值的物件的地址賦給了它。然而 model = h.getInfo(); 又把它指向了另外一個地址,也就是說原來開闢的記憶體並沒有用,也就沒什麼意義。
形象的比喻也就是像網上說的:
有對夫妻要生小孩,如果已經生下來了,取名字叫做“小明”,那麼“小明’就是陣勢存在這個世界上的,那就是new出來了;
如果還沒有生下來,只是去了一個名字叫做“小明”,目前並沒有真正存在在這個世界上,那就是為null。
new出來的已經是實體了,這個實體會佔用記憶體的,並且是一個物件的形式存在的;而null並不會佔用記憶體,只是一個空的指向。

二、”String data;” “String data = null;” “String data = “a”;” “String data = new String(“a”);” 的區別:
1、”String data;” 只是定義了一個String型別的變數data,並沒有給它賦值,在java中,預設在使用一個變數的時候必須給這個變數賦予初始值。data是一個引用,它不是物件。為一個沒有初始化的引用;
2、”String data = null;” 定義了一個String型別的變數data,並賦予它初始值, 初始值為空(null)。是一個空引用;
3、”String data = “a”;” 定義了一個String型別的變數data,並賦予它初始值, 初始值為“a”。屬於在字串池裡寫入一個字元“a”,然後用data指向它;
4、“String data = new String(“a”);” 和 “String data = “a”;” 是有本質區別的,前者是在堆上建立一個內容為“a”的字串物件。後者是在字串池裡寫入一個字元“a”,然後用data指向它。
“String data = “a”;” 是在棧上分配記憶體的,速度更快; “String data = new String(“a”);” 是在堆上分配記憶體的;
“String data;” 只是給data分配一個記憶體空間,系統會自動賦值為null;
“String data = null;” 是分配的空間中儲存的值為null空值;
“String data = “a”;” 是分配的空間中儲存的值為a;
在java環境中打印出來的時候(System.out.Println(data);),第一個會出現異常,必須給data變數賦初始值;第二個會輸出null;第三個輸出a;第四個輸出a。

三、null和“”的區別:
NULL :代表聲明瞭一個空物件,根本就不是一個字串。對空物件做任何操作都不行的,除了=和==;
“” :代表聲明瞭一個物件例項,這個物件例項的值是一個長度為0的空字串。
String s = null; 只是定義了一個控制代碼,也就是說你有了個引用,但是這個引用未指向任何記憶體空間;
String s = “”; 這個引用已經指向了一塊是空字串的記憶體空間,是一個實際的東西,可以對它進行操作;

四、在判斷中a==”“和a==null有何不同
如果沒有給a賦過值,a==”“會導致異常。 null是用來判斷引用型別是否分配了儲存空間,”“是針對字串的;
在實際處理時,往往認為”“和null代表相同的含義,即都代表無值。
此時建議用如下語法: if(a == null || a == “”){ }
如果a為null,就不會執行後面的判斷,直接返回true。
string型別實際上是字串指標,也即是一個引用型別 ,所以如果沒有給a賦過值,a==”“會導致異常 所以if(a == null || a == “”){ }這種寫法也是正確的。