值類型與引用類型,==比較這兩種的差別
JAVA中值類型和引用類型的不同
1、 JAVA中值類型和引用類型的不同?
[定義]
引用類型表示你操作的數據是同一個,也就是說當你傳一個參數給另一個方法時,你在另一個方法中改變這個變量的值,
那麼調用這個方法是傳入的變量的值也將改變.值類型表示複製一個當前變量傳給方法,
當你在這個方法中改變這個變量的值時,最初生命的變量的值不會變.通俗說法: 值類型就是現金,要用直接用;引用類型是存摺,要用還得先去銀行取現。----(摘自網上)
[值類型]
也就是基本數據類型 基本數據類型常被稱爲四類八種
四類:
1,整型 2,浮點型 3,字符型4,邏輯型
八種:
1,整型3種 byte,short,int,long
2,浮點型2種 float,double
3,字符型1種 char
4,邏輯型1種 boolean
[引用類型]
除了四類八種基本類型外,所有的類型都稱爲引用類型(數組,類,接口,字符串)
在弄清楚值類型與引用類型之後,最後一點就是值傳遞與引用傳遞,這纔是關鍵
[值傳遞]
基本數據類型賦值都屬於值傳遞,值傳遞傳遞的是實實在在的變量值,是傳遞原參數的拷貝,值傳遞後,實參傳遞給形參的值,形參發生改變而不影響實參。
[引用傳遞]
引用類型之間賦值屬於引用傳遞。引用傳遞傳遞的是對象的引用地址,也就是它的本身(自己最通俗的理解)。
引用傳遞:傳的是地址,就是將實參的地址傳遞給形參,形參改變了,實參當然被改變了,因爲他們指向相同的地址。
引用和我們的指針差不多,但是它不又不需要我們去具體的操作
[內存分配]
一個具有值類型(value type)的數據存放在棧內的一個變量中。即是在棧中分配內存空間,直接存儲所包含的值,其值就代表數據本身。
值類型的數據具有較快的存取速度。
一個具有引用類型(reference type)的數據並不駐留在棧中,而是存儲於堆中。即是在堆中分配內存空間,不直接存儲所包含的值,而是指向所要存儲的值,其值代表的是所指向的地址。當訪問一個具有引用類型的數據時,需要到棧中檢查變量的內容,該變量引用堆中的一個實際數據。引用類型的數據比值類型的數據具有更大的存儲規模和較低的訪問速度。
Java中有垃圾回收機制,棧內存中的變量隨着方法的結束內存自然銷燬了,而用引用類型的時候,當方法結束的時候,這個對象可能被另一個引用類型所應用,不會銷燬,只有當一個對象沒有任何引用變量引用的時候,垃圾回收機制纔會回收
2,爲什麼Java中數據的存放有堆和棧之分?
==判斷String
Java中的String str=“abc”; String str=new String(“abc”);和String str = new String();的區別以及==與equals()的不同。
Java運行環境有一個字符串池,由String類維護。執行語句String str=“abc"時,首先查看字符串池中是否存在字符串"abc”,如果存在則直接將"abc"賦給str,如果不存在則先在字符串池中新建一個字符串"abc",然後再將其賦給str。執行語句String
str=new String(“abc”)時,不管字符串池中是否存在字符串"abc",直接新建一個字符串"abc"(注意:新建的字符串"abc"不是在字符串池中),然後將其付給str。前一語句的效率高,後一語句的效率低,因爲新建字符串佔用內存空間。String str = new String()創建了一個空字符串,與String str=new String("")相同。下面舉個例子說明:
public class CompareString {
public static void main(String[] args) {
String a = new String();
String aa = “”;
String aaa = new String("");
String b = new String(“asdf”);
String c = new String(“asdf”);
String d = “asdf”;
System.out.println(a == aa); //false
System.out.println(a == aaa);
//false
System.out.println(a.intern() == aa.intern());
//true
System.out.println(a.intern() == aaa.intern());
//true
System.out.println(d == “asdf”);
//true
System.out.println(b == c);
//false
System.out.println(b == d);
//false
System.out.println(b.equals©);
//true
System.out.println(b.equals(d));
//true
b = b.intern();
System.out.println(b == c); //false
System.out.println(b == d);
//true
c = c.intern();
System.out.println(b == c);
//true
}
}
從運行結果可以驗證前面所述的內容。如果不懂String
類的intern()方法的用法可以參考jdk自帶的文檔.
從CompareString類中我們也可以看出==與equals()的不同之處:即==比較的是兩個對象的引用(即內存地址)是否相等,而equals()比較的是兩個對象裏的內容(即內存地址裏存放的東西)是否相等。當然equals()在個別類中被重寫了那就例外了。
instance of是判斷一個object是不是屬於某個類的
測試代碼
public class ValDiffierquote {
int value = 100;
int value2 = 100;
String string = "abc";
String string1 = "abc";
String string2 = new String("abc");
public void Modify(int i){
i = 200;
}
public void ModifyString(String s){
s.toUpperCase();
}
public static void main(String[] args) {
int valModify = 100;
String strModify = "abc";
String str = strModify;
ValDiffierquote valDiffierquote = new ValDiffierquote();
if (valDiffierquote.value == valDiffierquote.value2)
System.out.println("值類型相同值相等");
else
System.out.println("值類型相同值不等");
if (valDiffierquote.string == valDiffierquote.string2)
System.out.println("引用類型相同字符串等號判斷相等");
else
System.out.println("引用類型相同字符串等號判斷不等");
if (valDiffierquote.string == valDiffierquote.string1)
System.out.println("引用類型相同字符串等號判斷相等");
else
System.out.println("引用類型相同字符串等號判斷不等");
if (valDiffierquote.string.equals(valDiffierquote.string2))
System.out.println("引用類型變量使用equals()判斷內容相同");
valDiffierquote.Modify(valModify);
System.out.println("更新後的Int值(更新前100): " + valModify);
valDiffierquote.ModifyString(strModify);
System.out.println("更新後的String內容(更新前abc):" +
strModify);
strModify = "efg";
System.out.println(str+strModify);
//在爲對象“賦值”的時候,對一個對象進行操作時,我們真正操作的是對
// 對象的引用,所以倘若“將一個對象賦值給另一個對象”,實際是將“
// 引用”從一個地方複製到另一個地方。
ValDiffierquote valDiffierquote1 = new ValDiffierquote();
valDiffierquote = valDiffierquote1;
System.out.println(valDiffierquote.string+valDiffierquote1.string);
valDiffierquote.string = "efg";
System.out.println(valDiffierquote.string+valDiffierquote1.string);
}
}