亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Java 中的類型、值和變量 之 基本類型

beita / 3180人閱讀

摘要:在中存在兩種類型基本類型和引用類型。值得注意的是,基本類型的值的狀態(tài)不會被共享。浮點類型和它們的值中的浮點類型遵循標準的定義。布爾類型和它們的值類型表示兩個邏輯量,和。

眾所周知,Java是一門靜態(tài)類型的語言,這意味著所有的變量和表達式的類型會在編譯時確定。同時,Java 還是一門強類型的語言,因此變量的值或表達式的結(jié)果的類型都會受到限制(比如一個聲明為 String 的變量不的值不可能是一個數(shù)值 1),類型之間的運算也會被限制,這有助于在編譯時發(fā)現(xiàn)絕大多數(shù)的錯誤。

Java中存在兩種類型:基本類型和引用類型。

PrimitiveType:
    {Annotation} NumericType
    {Annotation} boolean
    
NumericType:
    IntegralType
    FloatingPointType
    
IntegralType:
    (one of)
    byte short int long char

FloatingPointType:
    (one of)
    float double
Java Language Specification (Java SE 8 Edition)  §4.2 Primitive Types and Values

值得注意的是,基本類型的值的狀態(tài)不會被共享。

比如下面這個例子:

int i = 0;
int j = i;
i += 1;
System.out.println(j);

AtomicInteger i = new AtomicInteger(0);
AtomicInteger j = i;
i.addAndGet(1);
System.out.println(j);

上述代碼將輸出:

0
1
整數(shù)類型和它們的值

整數(shù)類型 (IntegralType) 包含了以下五種類型:

類型 長度 / 位 (bit) 取值范圍
byte 有符號 8 -128 ~ 127
short 有符號 16 -32768 ~ 32767
int 有符號 32 -214783648 ~ 2147483647
long 有符號 64 -9223372036854775808 ~ 9223372036854775807
char 無符號 16 u0000 ~ uffff 等價于 0 ~ 65535
整數(shù)類型所支持的運算

比較運算符: <、<=、>、>= 、==、!= ,其結(jié)果為 boolean 類型;

數(shù)值運算符:

一元運算符: + 、-

乘法運算符: *、/、%

加法運算符: + 、-

自增運算符: ++, 分為前綴自增 (++i) 和后綴自增 (i++)

自減運算符: --, 分為前綴自減 (--i) 和后綴自減 (i--)

位移運算符:

左移運算符: <<

有符號右移: >>

無符號右移: >>>

按位互補運算符: ~

整數(shù)按位運算符: &、^、|

條件運算符: ? :

類型轉(zhuǎn)換運算符: cast

字符串拼接運算符: +

這里面加號出現(xiàn)了好幾次,包括 一元運算符、加法運算符自增運算符、字符串拼接運算符,后三者運算符就如它們的字面意思般,很好理解。

那么 一元運算符 是什么意思呢?

讓我們來看看下面這份代碼:

static void is (short i) {
    System.out.println("short");
}

static void is (int i) {
    System.out.println("int");
}

static void is (long i) {
    System.out.println("long");
}

static void main (String[] args) {
    short i = 5;
    int j = 10;
    is(i);
    is(+i);
    is(-i);
    is(j);
    is(+j);
    is(-j);
}

上述代碼將輸出:

short
int
int
int
int
int

很顯然,第 17~19 行的調(diào)用執(zhí)行的是參數(shù)類型為 int 的方法,然而第 20~21 行的調(diào)用執(zhí)行的并不是參數(shù)類型為 long 的方法。

我在 JSL § 15.15.3 Unary Plus Operator + 中并未看出一元運算符的具體影響,根據(jù)實驗結(jié)果只能推測一元運算符會將低于 int 的數(shù)值類型提升到 int 類型 (你可以聲明一個 byte h = 0,is(+h) 仍然會調(diào)用參數(shù)類型為 int 的方法),而且對于 +- 都是提升類型的作用,并不是直覺意義上的一個升一個降。

關(guān)于這個 一元運算符 的用法其實并不是很多,有下列幾種:

// 如果方法接受的是 int 類型的話,僅僅用來明確這是個正數(shù)還是負數(shù)。
func(+1);
func(-1);

// 輸出字符的代碼值時的小技巧
// 因為字符類型 char 是低于 int 的整數(shù)類型
System.out.println(+"c"); // 99
整數(shù)運算的溢出和可能引發(fā)的異常

對于移位運算符以外的整數(shù)運算而言,如果兩個操作數(shù)中至少有一個 long ,那么這次運算將會按 64位精度進行計算,并且其計算結(jié)果也是 long 類型,此時如果另一個操作數(shù)不是 long,那么會將它提升到 long 類型再計算;如果兩個操作數(shù)都不是 long,那么會按 32位精度進行計算,并且計算結(jié)果為 int,如果任何一個操作數(shù)不是 int, 那么都將提升到 int 類型后再計算。

整數(shù)運算符會在以下情況拋出異常:

涉及到對引用類型拆箱時,如果是空引用,那么會拋出 NullPointerException

如果右操作數(shù)為零,那么整數(shù)除法運算符和整數(shù)取余運算符都會拋出 ArithmeticException

在自增和自減的時候,如果涉及到拆箱裝箱且內(nèi)存不足,會拋出 OutOfMemoryError

來看看規(guī)范中給出的示例代碼:

class Test {
    public static void main (String[] args) {
        int i = 1000000;
        System.out.println(i * i);
        long l = i;
        System.out.println(l * l);
        System.out.println(20296 / (l - i));
    }
}

上述代碼將輸出:

-727379968
1000000000000
ArithmeticException

對于 int 來說,1000000^2 太大了,而由于之前的運算規(guī)則,i * i 只能保存結(jié)果的低32位,十進制下也就是 -727379968

浮點類型和它們的值

Java 中的浮點類型遵循 IEEE 754 標準的定義。

IEEE 754-1985 - Wikiwand

IEEE 754_百度百科

IEEE 754 標準中,定義了 32位精度的 float、64位精度的 double,還有正負數(shù)、正負0、正負無窮和特殊的 NaN

NaN 用于表示無效操作的結(jié)果,比如 0.0 / 0.0 (0 / 0 才適用整數(shù)運算中的 右操作數(shù)為0 的異常規(guī)則),你可以在 Float.NaNDouble.NaN 中找到。

NaN 是無序的,因此

如果一次運算中一個或兩個操作數(shù)都是 NaN,則比較運算符 (<、<=、>、>=) 都會返回 false

如果操作數(shù)是 NaN,則相等運算符 (==) 返回 false

如果 xyNaN,則 (x < y) == !(x >= y) 將返回 false

如果任一操作數(shù)是 NaN, 則不等式運算符 != 將返回 true

當(dāng)且僅當(dāng) xNaN 時,x != x 將返回 true

浮點類型所支持的運算

比較運算符: <、<=、>、>= 、==、!= ,其結(jié)果為 boolean 類型;

數(shù)值運算符:

一元運算符: + 、-

乘法運算符: *、/%

加法運算符: + 、-

自增運算符: ++, 分為前綴自增 (++i) 和后綴自增 (i++)

自減運算符: --, 分為前綴自減 (--i) 和后綴自減 (i--)

條件運算符: ? :

類型轉(zhuǎn)換運算符: cast

字符串拼接運算符: +

如果一次計算中,至少有一個二元運算符的操作數(shù)是浮點類型的,那么該操作就是一個浮點運算,即使另一個操作數(shù)是整數(shù)。

System.out.println(10 * 0.1); // 1.0

對于浮點運算而言,如果兩個操作數(shù)中至少有一個 double,那么這次運算將會按 64位精度進行計算,并且其計算結(jié)果也是 double 類型,此時如果另一個操作數(shù)不是 double,那么會將它提升到 double 類型再計算;如果兩個操作數(shù)都不是 double,那么會按 32位精度進行計算,并且計算結(jié)果為 float,如果任何一個操作數(shù)不是 float, 那么都將提升到 float 類型后再計算。

浮點運算的溢出和可能引發(fā)的異常

浮點運算有溢出 (overflows) 和下溢 (underflows),其中溢出將產(chǎn)生有符號的無窮大,而下溢則產(chǎn)生一個非標準化 (denormalized) 的值或是一個有符號的0。

數(shù)學(xué)上無法確定結(jié)果的浮點運算將產(chǎn)生 NaN。

所有 NaN 參與的浮點運算都會產(chǎn)生 NaN。

在下列情況中,浮點運算會拋出異常:

計算時需要拆箱,而又是個空引用時,會拋出 NullPointerException

自增自減的情況下,如果需要拆箱裝箱且內(nèi)存不夠時,會拋出 OutOfMemoryError。

接下來看看規(guī)范中給出的示例代碼:

class Test {
    public static void main(String[] args) {
        // 溢出
        double d = 1e308;
        System.out.print("溢出產(chǎn)生了無窮大: ");
        System.out.println(d + "*10==" + d*10);
        // 漸變下溢 (gradual underflow)
        d = 1e-305 * Math.PI;
        System.out.print("漸變下溢: " + d + "
   ");
        for (int i = 0; i < 4; i++)
            System.out.print(" " + (d /= 100000) + "
");
        System.out.println();
        // 產(chǎn)生 NaN
        System.out.print("0.0/0.0 產(chǎn)生的不是數(shù)字: ");
        d = 0.0/0.0;
        System.out.println(d);
        // 產(chǎn)生不精確結(jié)果的四舍五入:
        System.out.print("單精度下的不精確結(jié)果:");
        for (int i = 0; i < 100; i++) {
            float z = 1.0f / i;
            if (z * i != 1.0f)
                System.out.print(" " + i);
        }
        System.out.println();
        // 另一個產(chǎn)生不精確結(jié)果的四舍五入:
        System.out.print("雙精度下的不精確結(jié)果:");
        for (int i = 0; i < 100; i++) {
            double z = 1.0 / i;
            if (z * i != 1.0)
                System.out.print(" " + i);
        }
        System.out.println();
        // 轉(zhuǎn)換到整數(shù)時發(fā)生的結(jié)果階段:
        System.out.print("強制轉(zhuǎn)換到整數(shù): ");
        d = 12345.6;
        System.out.println((int)d + " " + (int)(-d));
    }
}

上述代碼將輸出

溢出產(chǎn)生了無窮大: 1.0e + 308 * 10 == Infinity
漸變下溢: 3.141592653589793E-305
 3.1415926535898E-310
 3.141592653E-315
 3.142E-320 0.0
 0.0 / 0.0 產(chǎn)生的不是數(shù)字:NaN
單精度下的不精確結(jié)果:0 41 47 55 61 82 83 94 97
雙精度下的不精確結(jié)果:0 49 98
強制轉(zhuǎn)換到整數(shù):12345 -12345

值得注意的是,在 漸變下溢 的例子中,我們可以看到精度逐漸喪失。

布爾類型和它們的值

boolean 類型表示兩個邏輯量,truefalse。

布爾運算符是:

關(guān)系運算符 ==!=

邏輯補足運算符 !

邏輯運算符& , ^|

條件運算符和條件運算符&&||

條件運算符? :

字符串連接運算符 + ,當(dāng)給定一個String操作數(shù)和一個 boolean 操作數(shù)時,它將把 boolean 操作符轉(zhuǎn)換為一個String"true""false" ),然后產(chǎn)生一個新創(chuàng)建的String,其值為兩個字符串的連接結(jié)果。

布爾表達式?jīng)Q定了幾種語句中的控制流:

if 語句

while 語句

do 語句

for 語句

一個boolean表達式還決定在 ? : 運算符中使用哪個子表達式的值作為結(jié)果 。

只有Boolean表達式和Boolean表達式可以在控制流程語句中使用。

通過表達式 x!=0 ,可以將整數(shù)或浮點表達式 x 轉(zhuǎn)換為 boolean 值,這遵循了 C 語言約定,即任何非零值為true 。

通過表達式 obj!=null ,可以將對象引用 obj 轉(zhuǎn)換為boolean值,這同樣遵循了 C 語言約定(除null之外的任何引用為true 。

參考資料: Java Language Specification (Java SE 8 Edition) § 4.2  

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

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/68875.html

相關(guān)文章

  • Java是傳值還是傳址

    摘要:傳值和傳址有什么區(qū)別是傳值還是傳址開始在傳參時,是傳值還是傳址傳值和傳址假設(shè)要將傳到。傳值和傳址是傳值是傳值。分別是基本類型,對象和數(shù)組,還有。常量池時,好比是一張紙條,當(dāng)要傳值給時,事實是把紙條上的內(nèi)容抄給了。 傳值和傳址有什么區(qū)別?Java是傳值還是傳址? 開始 Java在傳參時,是傳值還是傳址? 傳值和傳址 假設(shè)要將A傳到B。如果是傳值,就意味著將A中存放的值復(fù)制一份給B,B存的...

    fnngj 評論0 收藏0
  • Java并發(fā)編程的藝術(shù)】第二章讀書筆記原子操作

    摘要:前言今天的筆記來了解一下原子操作以及中如何實現(xiàn)原子操作。概念原子本意是不能被進一步分割的最小粒子,而原子操作意為不可被中斷的一個或一系列操作。處理器實現(xiàn)原子操作處理器會保證基本內(nèi)存操作的原子性。 showImg(https://segmentfault.com/img/bVVIRA?w=1242&h=536); 前言 今天的筆記來了解一下原子操作以及Java中如何實現(xiàn)原子操作。 概念 ...

    olle 評論0 收藏0
  • Java虛擬機如何加載類的?

    摘要:虛擬機有個一加載機制,叫做雙親委派模型。擴展類加載器擴展類加載器的父類的加載器是啟動類加載器。驗證驗證的目的就是需要符合虛擬機的規(guī)范。虛擬機會通過加鎖的方式確保方法只執(zhí)行一次。 引言 上一篇文章談到Java運行的流程,其中有一環(huán)是類加載。今天就繼續(xù)深入探討JVM如何加載虛擬機。首先JVM加載類的一般流程分三步:·加載·鏈接·初始化那么是否全部Java類都是這樣三步走的方式加載呢?我們可...

    TANKING 評論0 收藏0
  • Java編程思想》讀書筆記-類與對象

    摘要:類最基本的作用,在于通過類獲取到相應(yīng)的對象,在向?qū)ο蟀l(fā)送消息時以期望對象做某些特定的事情。先導(dǎo)概念引用中一切皆對象,因此采用一個指向?qū)ο蟮囊脕聿倏v對象。對象可以存活于作用域之外。 歡迎各位讀者關(guān)注我的微信公眾號,共同探討Java相關(guān)技術(shù)。生命不止,學(xué)習(xí)不休! showImg(https://segmentfault.com/img/bVboaBO?w=129&h=129); 也許你慢...

    NickZhou 評論0 收藏0
  • 談?wù)?em>Java的面向?qū)ο?/b>

    摘要:也就是說,一個實例變量,在的對象初始化過程中,最多可以被初始化次。當(dāng)所有必要的類都已經(jīng)裝載結(jié)束,開始執(zhí)行方法體,并用創(chuàng)建對象。對子類成員數(shù)據(jù)按照它們聲明的順序初始化,執(zhí)行子類構(gòu)造函數(shù)的其余部分。 類的拷貝和構(gòu)造 C++是默認具有拷貝語義的,對于沒有拷貝運算符和拷貝構(gòu)造函數(shù)的類,可以直接進行二進制拷貝,但是Java并不天生支持深拷貝,它的拷貝只是拷貝在堆上的地址,不同的變量引用的是堆上的...

    ormsf 評論0 收藏0

發(fā)表評論

0條評論

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