Java 數(shù)據(jù)類型及其判斷

一兆解、Java中的數(shù)據(jù)類型,可分為兩類:

1.基本數(shù)據(jù)類型跑揉,也稱原始數(shù)據(jù)類型:

byte锅睛、short、char历谍、int现拒、long、float望侈、double印蔬、boolean它們之間的比較,應(yīng)該用雙等號(==)比較的是它們的值甜无。

2.引用數(shù)據(jù)類型:

JAVA當(dāng)中所有的類都是繼承于Object這個基類的扛点,在Object中的基類中定義了一個equals的方法哥遮,這個方法的初始行為是比較變量(棧)內(nèi)存中存放的對象的(堆)內(nèi)存地址,用來判斷兩個對象的地址是否相同陵究,即是否是指相同一個對象眠饮。比較的是真正意義上的指針操作。
但在一些類庫當(dāng)中這個方法被覆蓋掉了铜邮,如String仪召、Integer、Date松蒜。在這些類當(dāng)中equals有其自身的實現(xiàn)扔茅,而不再是比較類在堆內(nèi)存中的存放地址了。
對于引用數(shù)據(jù)類型之間進(jìn)行equals比較秸苗,在沒有重寫equals方法的情況下召娜,它們之間的比較還是基于它們在內(nèi)存中的存放位置的地址值的,因為Object的equals方法也是用雙等號進(jìn)行比較的惊楼,所以比較后的結(jié)果跟雙等號的結(jié)果相同玖瘸。

注意:

  1. 比較的是操作符兩端的操作數(shù)是否是同一個對象。
  2. 兩邊的操作數(shù)必須是同一類型的(可以是父子類之間)才能編譯通過檀咙。
  3. 比較的是地址雅倒。如果是具體的阿拉伯?dāng)?shù)字的比較,值相等則為true弧可,如:
    int a=10 與 long b=10L 與 double c=10.0都是相同的(為true)蔑匣,因為他們都指向地址為10的堆。
  4. String s=“abc"是一種非常特殊的形式棕诵,和new 有本質(zhì)的區(qū)別裁良。它是java中唯一不需要new就可以產(chǎn)生對象的途徑。以 String s=“abc”; 形式賦值在java中叫直接量年鸳,它是在常量池中而不是象new一樣放在壓縮堆中趴久。這種形式的字符串,在JVM內(nèi)部發(fā)生字符串拘留搔确,即當(dāng)聲明這樣的一個字符串后彼棍,JVM會在常量池中先查找有有沒有一個值為"abc"的對象。如果有膳算,就會把它賦給當(dāng)前引用座硕。即原來那個引用和現(xiàn)在這個引用指向了同一對象。如果沒有涕蜂,則在常量池中新創(chuàng)建一個"abc”华匾,下一次如果有 String s1 = “abc”; 又會將s1指向"abc"這個對象,即以這種形式聲明的字符串机隙,只要值相等蜘拉,任何多個引用都指向同一對象萨西。
      而 String s = new String(“abcd”); 和其它任何對象一樣,每調(diào)用一次就產(chǎn)生一個對象旭旭,只要它們調(diào)用谎脯。
      也可以這么理解: String str = “hello”; 先在內(nèi)存中找是不是有"hello"這個對象,如果有持寄,就讓str指向那個"hello"源梭。如果內(nèi)存里沒有"hello",就創(chuàng)建一個新的對象保存"hello"稍味。String str=new String (“hello”) 就是不管內(nèi)存里是不是已經(jīng)有"hello"這個對象废麻,都新建一個對象保存"hello"。

具體可以看下面的代碼:

public class test1 { 
    public static void main(String[] args) { 
         String a = new String("ab"); // a 為一個引用     
         String b = new String("ab"); // b為另一個引用,對象的內(nèi)容一樣
         String aa = "ab"; // 放在常量池中     
         String bb = "ab"; // 從常量池中查找   
         if (aa == bb){ 
            System.out.println("aa==bb");// true
         }       
         if (a == b){             
            System.out.println("a==b");// false模庐,非同一對象 
         }      
        if (a.equals(b)){          
            System.out.println("aEQb");// true 
         }         
        if (42 == 42.0) {            
             System.out.println("true");15 // true   
        } 
     }
}

二烛愧、equals和==的區(qū)別

equals方法最初是在所有類的基類Object中進(jìn)行定義的,源碼:

public boolean equals(Object obj) {    
   return (this == obj);
}

由equals的源碼可以看出這里定義的equals與雙等號是等效的(Object類中的equals與雙等號沒什么區(qū)別)掂碱。不同的原因就在于有些類(像String屑彻、Integer等類)對equals進(jìn)行了重寫,但是沒有對equals進(jìn)行重寫的類(比如我們自己寫的類)就只能從Object類中繼承equals方法顶吮,其equals方法與==就也是等效的,除非在此類中重寫equals粪薛。

對equals重新需要注意五點:
1??自反性:對任意引用值X悴了,x.equals(x)的返回值一定為true。
2??對稱性:對于任何引用值x违寿、y湃交,當(dāng)且僅當(dāng)y.equals(x)返回值為true時,x.equals(y)的返回值一定為true藤巢。
3??傳遞性:如果x.equals(y)=true搞莺,y.equals(z)=true,則x.equals(z)=true掂咒。
4??一致性:如果參與比較的對象沒任何改變才沧,則對象比較的結(jié)果也不應(yīng)該有任何改變。
5??非空性:任何非空的引用值X绍刮,x.equals(null)的返回值一定為false 温圆。

String類對equals的重寫如下:

public boolean equals(Object var1) {
        if (this == var1) {
            return true;
        } else {
            if (var1 instanceof String) {
                String var2 = (String) var1;
                int var3 = this.value.length;
                if (var3 == var2.value.length) {
                    char[] var4 = this.value;
                    char[] var5 = var2.value;

                    for (int var6 = 0; var3-- != 0; ++var6) {
                        if (var4[var6] != var5[var6]) {
                            return false;
                        }
                    }
                    return true;
                }
            }
            return false;
        }
    }

另外,雙等號比"equals"運(yùn)行速度快孩革,因為雙等號"=="只是比較引用岁歉。

三、經(jīng)典案例

如果Integer a = 3;Integer b = 3;那么【a==b】的結(jié)果是什么膝蜈?-----true
如果Integer a = 273;Integer b = 273;那么【a==b】的結(jié)果是什么锅移?-----false

原因:對于Integer var = ?在-128至127范圍內(nèi)的賦值熔掺,Integer對象是在 IntegerCache.cache產(chǎn)生,會復(fù)用已有對象非剃,這個區(qū)間內(nèi)的Integer值可以直接使用==進(jìn)行判斷置逻,但是這個區(qū)間之外的所有數(shù)據(jù),都會在堆上產(chǎn)生努潘,并不會復(fù)用已有對象诽偷,推薦使用equals方法進(jìn)行判斷。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疯坤,一起剝皮案震驚了整個濱河市报慕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌压怠,老刑警劉巖眠冈,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異菌瘫,居然都是意外死亡蜗顽,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門雨让,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雇盖,“玉大人,你說我怎么就攤上這事栖忠〈尥冢” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵庵寞,是天一觀的道長狸相。 經(jīng)常有香客問我,道長捐川,這世上最難降的妖魔是什么脓鹃? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮古沥,結(jié)果婚禮上瘸右,老公的妹妹穿的比我還像新娘。我一直安慰自己渐白,他們只是感情好尊浓,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著纯衍,像睡著了一般栋齿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天瓦堵,我揣著相機(jī)與錄音基协,去河邊找鬼。 笑死菇用,一個胖子當(dāng)著我的面吹牛澜驮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惋鸥,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼杂穷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了卦绣?” 一聲冷哼從身側(cè)響起耐量,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滤港,沒想到半個月后廊蜒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡溅漾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年山叮,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片添履。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡屁倔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出暮胧,到底是詐尸還是另有隱情汰现,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布叔壤,位于F島的核電站,受9級特大地震影響口叙,放射性物質(zhì)發(fā)生泄漏炼绘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一妄田、第九天 我趴在偏房一處隱蔽的房頂上張望俺亮。 院中可真熱鬧,春花似錦疟呐、人聲如沸脚曾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽本讥。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拷沸,已是汗流浹背色查。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留撞芍,地道東北人秧了。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像序无,于是被迫代替她去往敵國和親验毡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容