国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[Java] 變量里存的到底是什么

gaara / 2996人閱讀

摘要:,變量里存的是什么在規(guī)范中,對于有這么一句話一個可以是一個類的實(shí)例或者是一個數(shù)組一個數(shù)組其實(shí)是一個,不過這是另一個話題了。由于的設(shè)計(jì)是不可變的,在一個實(shí)例上的任何增刪操作都會產(chǎn)生一個新的實(shí)例,效果與重新為變量設(shè)定新的引用值是一樣的。

考慮下面這個例子:

Long l1 = 1L;
Long l2 = 2L;
Long l3 = 3L;
long l4 = 3L;
Long l5 = 1 + 2L;
System.out.println(l3 == 3);
System.out.println(l4 == 3);
System.out.println(l3.equals(3));
System.out.println(l3.equals(l4));
System.out.println(l3.equals(l5));

輸出的結(jié)果是

true
true
false
true
true

相信這個例子很多初學(xué)者都犯過迷糊:l3、l4 不都是 3 嗎,怎么 l3.equals(3)false 呢。

這里面有很多點(diǎn)可以講的,我們一個一個來看:

Longlong

Java 里只有兩種類型: primitive types 原始類型 和 reference types 引用類型。

null 是一種特殊的類型

規(guī)范說明:4.1. The Kinds of Types and Values

原始類型里包括:boolean、byte、short、int、long、char、float、double
引用類型有四種:class、interface、type、array (其中 type 我們平時遇到過的就是泛型 T,詳細(xì)內(nèi)容可以查閱規(guī)范 4.4. Type Variables)

所以這里,long 是原始類型,Long 是引用類型,這很重要,是接下來討論的基礎(chǔ)。

Boxing ConversionUnboxing Conversion

其實(shí)這個就是拆箱裝箱,這個知識點(diǎn)應(yīng)該不陌生吧,就是 Java 會自動幫你把原始數(shù)值類型和原始浮點(diǎn)類型轉(zhuǎn)換為對應(yīng)的引用類型,如 long 轉(zhuǎn)換為 Long。

舉個栗子:

public void func(Long l) {
    System.out.println(l);
}

func(1L);

這段代碼是可以跑起來的,但是如果調(diào)用時是這樣的 func(1),那么就會報(bào)錯,因?yàn)?1 是整數(shù)型,它即便自動裝箱也是 Integer 而不是 Long。

Objects,變量里存的是什么

在規(guī)范中,對于 Obejct 有這么一句話:

An object is a class instance or an array.
一個 Object 可以是一個類的實(shí)例或者是一個數(shù)組 (一個數(shù)組其實(shí)是一個 Object,不過這是另一個話題了。)
The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object.
引用值(通常是引用)是指向這些對象的指針和一個特殊的null引用,它不引用任何對象。

有些學(xué)過 C++ 的或是有 引用 這個概念的其他語言的同學(xué),可能在這里要犯迷糊了:不是說 Java 里沒有引用嗎,怎么規(guī)范里又提到這個詞了。

 注意,C 里面沒有引用只有指針,它跟 Java 一樣是值傳遞的。

其實(shí)可以這么不嚴(yán)謹(jǐn)?shù)卣J(rèn)為:C++ 里的 引用 是動詞,Java 里的 引用 是名詞。

C++ 里的引用是對一個變量定義一個別名:

int a = 2, int &ra = a;
// a為目標(biāo)原名稱,ra為目標(biāo)引用名。給ra賦值:ra = 1; 等價于 a = 1;
C++ 引用

Java 里的引用就是一個值,一個指向 對象 的值。

public static void func(String s) {
    s = "bar";
}

String s1 = "foo";
func(s1);
System.out.println(s1); // "foo"

在這里,s1 的值并不是 foo,而是一個指向 其字段value值為 ["f", "o", "o"]String 實(shí)例 的引用。

比如說,再聲明一個 String s2 = "foo";,然后在 func(s1); 處下斷點(diǎn),可以看到:

可以看到,String{@xxx}value:byte[]{@xxx} 都是一樣的,因?yàn)樗鼈兙褪峭粋€對象,s1s2 這兩個變量的值是 指向了同一個對象(String{@674})引用。

如果我們在 func(String s) 里打斷點(diǎn),會發(fā)現(xiàn)在 func(s1) 的情況下,ss1引用值 是一樣的。

因?yàn)?Java 是值傳遞,只不過在引用類型的情況下,傳遞的這個值,就是 引用值。

當(dāng) func 內(nèi)部對這個 s 進(jìn)行操作后,我們再來看看func內(nèi)部斷點(diǎn)的情況:

public static void func(String s) {
    s = "bar";
    // 斷點(diǎn)處,此時 s 的引用值已經(jīng)變?yōu)?String{@674}
    // 即此時的 s 的引用值已經(jīng)不再是 s1 的引用值,自此它們已經(jīng)指向的是不同的對象了。
}
由于 String 的設(shè)計(jì)是不可變的,在一個 String 實(shí)例上的任何增刪操作都會產(chǎn)生一個新的 String 實(shí)例,效果與重新為變量設(shè)定新的引用值是一樣的。

我們再看看一個原始類型的斷點(diǎn)情況:

int i = 0;

對于原始類型的變量而言,它們的值就是本身。

==equals

== 操作符在規(guī)范里其實(shí)分了三種情況:

15.21.1. Numerical Equality Operators == and !=

15.21.2. Boolean Equality Operators == and !=

15.21.3. Reference Equality Operators == and !=

equalsObject 的方法,但是任何類都可以覆寫這個方法來實(shí)現(xiàn)自定義的實(shí)例間判斷,比如 Long.equals 就改成了這個樣子:

    /**
     * Compares this object to the specified object.  The result is
     * {@code true} if and only if the argument is not
     * {@code null} and is a {@code Long} object that
     * contains the same {@code long} value as this object.
     *
     * @param   obj   the object to compare with.
     * @return  {@code true} if the objects are the same;
     *          {@code false} otherwise.
     */
    public boolean equals(Object obj) {
        if (obj instanceof Long) {
            return value == ((Long)obj).longValue();
        }
        return false;
    }

也就是說,只要待判定對象不是 Long 或其子類,那么就直接返回 false。

結(jié)合前邊講的 int 在方法調(diào)用時會被自動裝箱成 Integer(如果參數(shù)不顯式要求 int 類型),很顯然,l3.equals(3) 會直接因?yàn)?Integer 3 不是 Long 而返回 false

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/68602.html

相關(guān)文章

  • C語言中數(shù)據(jù)的存儲

    摘要:這里強(qiáng)調(diào)一下,之前講過一個操作符按位取反操作符,區(qū)別一下他倆,按位取反操作符是針對二進(jìn)制數(shù)每一位全部都取反,包括符號位。 目錄 傳統(tǒng)藝能?過渡區(qū)?正片開始?數(shù)據(jù)類...

    LeanCloud 評論0 收藏0
  • 如何使用 volatile, synchronized, final 進(jìn)行線程間通信

    摘要:如線程執(zhí)行后,線程執(zhí)行,相當(dāng)于線程向線程發(fā)送了消息。我們可以利用這種互斥性來進(jìn)行線程間通信。 你是否真正理解并會用volatile, synchronized, final進(jìn)行線程間通信呢,如果你不能回答下面的幾個問題,那就說明你并沒有真正的理解: 對volatile變量的操作一定具有原子性嗎? synchronized所謂的加鎖,鎖住的是什么? final定義的變量不變的到底是什么...

    keithxiaoy 評論0 收藏0
  • 數(shù)據(jù)在內(nèi)存中的存儲

    摘要:文章目錄一數(shù)據(jù)類型二整型在內(nèi)存中的存儲原碼反碼補(bǔ)碼大小端三例題練習(xí)一數(shù)據(jù)類型在語言中有整型浮點(diǎn)型構(gòu)造類型指針類型等。正數(shù)的原反補(bǔ)碼都相同對于整形來說數(shù)據(jù)在內(nèi)存中存放的都是補(bǔ)碼。 ...

    BicycleWarrior 評論0 收藏0
  • JavaScript 函數(shù)式真正的淺析

    摘要:入門的導(dǎo)語廢話最近兩年你要說函數(shù)式編程不火的話那是不可能的是人都知道函數(shù)式編程很火為什么函數(shù)式編程會火呢在于它的思想很強(qiáng)大很強(qiáng)勢尤其是前端的更是在上完全使用純函數(shù)函數(shù)式的好處漸漸被發(fā)掘出來筆者最近看了一些函數(shù)式方面的東東現(xiàn)在發(fā)出來給大家學(xué)習(xí) 0x00 入門的導(dǎo)語(廢話) 最近兩年你要說函數(shù)式編程不火的話, 那是不可能的, 是人都知道函數(shù)式編程很火.為什么函數(shù)式編程會火呢, 在于它的思想...

    fox_soyoung 評論0 收藏0

發(fā)表評論

0條評論

gaara

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<