變量指程序運(yùn)行時(shí)可變的量,相當(dāng)開辟了一塊內(nèi)存空間來保存一些數(shù)據(jù),類型則是對(duì)變量的種類進(jìn)行劃分,使不同的類型變量具有不同的特性
而變量與我們內(nèi)存的硬件設(shè)施密切相關(guān)
JAVA是強(qiáng)類型語言
硬性指標(biāo) :
注意: 雖然語法上也允許使用中文/美元符($)命名變量, 但是 強(qiáng)烈 不推薦這樣做.
軟性指標(biāo) :
final int a = 10;
a = 20; // 編譯出錯(cuò). 提示 無法為最終變量a分配值 常量不能在程序運(yùn)行過程中發(fā)生修改
字面常量 ——程序中直接寫出來的值
幾種常數(shù)賦值方式
public class Candy3 {public static void main(String[] args) {int a=0x123;
int b=0b1001;
int c=010;
System.out.println(a);//291
System.out.println(b);//9
System.out.println(c);//8
}
}
基本類型基本語法格式
int a=10;//初始化時(shí)并賦值
int a;
內(nèi)存大小
int 大小為4個(gè)字節(jié)(byte),與操作系統(tǒng)的和JVM的版本無關(guān),像C語言可能就會(huì)受到編譯器的影響,是為了實(shí)現(xiàn)跨平臺(tái)
整型的范圍
數(shù)據(jù)溢出問題
為什么會(huì)溢出
因?yàn)?^32-1的數(shù)據(jù)的大小不夠用,還不夠表述出馬云的個(gè)人資產(chǎn),所以引出了long類型
長整型 longlong a=10L;
long a=10l;
long a=1000_000_000;//可以為數(shù)字字面量加下劃線,這些下劃線只是讓人更易讀,Java編譯器會(huì)自動(dòng)去除這些下劃線
為什么要加L呢?
整型的字面量,默認(rèn)是整型(int),浮點(diǎn)數(shù)的字面量,默認(rèn)是double,所以要加一個(gè)L(l)表示它是long類型,否則會(huì)發(fā)生隱式轉(zhuǎn)換
內(nèi)存的大小
long類型的大小是8字節(jié)
long的數(shù)據(jù)范圍
-263至263-1
短整型 shortshort a=20;
內(nèi)存大小
2個(gè)字節(jié) 數(shù)值范圍是 -215至-215-1
基本沒啥用
比特型 bytebyte a=1;
內(nèi)存大小
一個(gè)字節(jié) ,數(shù)值訪問 -128到127
主要用于文件和網(wǎng)絡(luò)的傳輸
浮點(diǎn)數(shù) float和doublefloat f=1.2f;
float f=1.2F;
double d=1.2;
在JAVA中直接寫出來的字母常量的浮點(diǎn)數(shù)都是double類型的,所以在flaot需要特別的聲明一下
內(nèi)存大小
float的大小為4個(gè)字節(jié),double的字節(jié)是8個(gè)字節(jié) 在內(nèi)存中采用指數(shù)的形式來模擬
浮點(diǎn)數(shù)存儲(chǔ)規(guī)則
根據(jù)國際標(biāo)準(zhǔn)IEEE(電氣和電子工程協(xié)會(huì)) 754,任意一個(gè)二進(jìn)制浮點(diǎn)數(shù)V可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^S S表示符號(hào)位,當(dāng)s=0,V為正數(shù);當(dāng)s=1,V為負(fù)數(shù)。
M表示有效數(shù)字,大于等于1,小于2。
2^E E表示指數(shù)位。
舉例來說:
十進(jìn)制的5.0,寫成二進(jìn)制是 101.0 ,相當(dāng)于 1.01×2^2 。
那么,按照上面V的格式,可以得出s=0,M=1.01,E=2。
十進(jìn)制的-5.0,寫成二進(jìn)制是 -101.0 ,相當(dāng)于 -1.01×2^2 。那么,s=1,M=1.01,E=2。
IEEE 754規(guī)定:
IEEE 754對(duì)有效數(shù)字M和指數(shù)E,還有一些特別規(guī)定。
前面說過, 1≤M<2 ,也就是說,M必須寫成 1.xxxxxx 的形式,其中xxxxxx表示小數(shù)部分。
IEEE 754規(guī)定,在計(jì)算機(jī)內(nèi)部保存M時(shí),默認(rèn)這個(gè)數(shù)的第一位總是1,因此可以被舍去,只保存后面的 xxxxxx部分。比如保存1.01的時(shí) 候,只保存01,等到讀取的時(shí)候,再把第一位的1加上去。這樣做的目的,是節(jié)省1位有效數(shù)字。以32位 浮點(diǎn)數(shù)為例,留給M只有23位, 將第一位的1舍去以后,等于可以保存24位有效數(shù)字。
至于指數(shù)E,情況就比較復(fù)雜。
首先,E為一個(gè)無符號(hào)整數(shù)(unsigned int)
這意味著,如果E為8位,它的取值范圍為0255;如果E為11位,它的取值范圍為02047。但是,我們知道,科學(xué)計(jì)數(shù)法中的E是可以出現(xiàn)負(fù)數(shù)的,所以IEEE 754規(guī)定,存入內(nèi)存時(shí)E的真實(shí)值必須再加上一個(gè)中間數(shù),對(duì)于8位的E,這個(gè)中間數(shù) 是127;對(duì)于11位的E,這個(gè)中間 數(shù)是1023。比如,2^10的E是10,所以保存成32位浮點(diǎn)數(shù)時(shí),必須保存成10+127=137,即 10001001。
然后,指數(shù)E從內(nèi)存中取出還可以再分成三種情況:
E不全為0或不全為1
這時(shí),浮點(diǎn)數(shù)就采用下面的規(guī)則表示,即指數(shù)E的計(jì)算值減去127(或1023),得到真實(shí)值,再將 有效數(shù)字M前加上第一位的1。
比如:0.5(1/2)的二進(jìn)制形式為0.1,由于規(guī)定正數(shù)部分必須為1,即將小數(shù)點(diǎn)右移1位,則為1.0*2^(-1),其階碼為-1+127=126,表示為 01111110,而尾數(shù)1.0去掉整數(shù)部分為0,補(bǔ)齊0到23位00000000000000000000000,則其二進(jìn) 制表示形式為:
E全為0
這時(shí),浮點(diǎn)數(shù)的指數(shù)E等于1-127(或者1-1023)即為真實(shí)值, 有效數(shù)字M不再加上第一位的1,而是還原為0.xxxxxx的小數(shù)。這樣做是為了表示±0,以及接近于0的很小的數(shù)字。
E全為1
這時(shí),如果有效數(shù)字M全為0,表示±無窮大(正負(fù)取決于符號(hào)位s);
關(guān)于3*0.1==0.3答案是不相同的
在上面,我們知道我們的浮點(diǎn)數(shù)在計(jì)算機(jī)以指數(shù)形式存儲(chǔ),其原理還是得用我們的二進(jìn)制來表示
如何解決
三種特殊的double如果的基本整數(shù)和浮點(diǎn)數(shù)的精度不能滿足需求,可以使用java.math包下兩個(gè)很有用的類
BigInteger 實(shí)現(xiàn)任意精度的整數(shù)運(yùn)算
- BigInteger a=new BigInteger(“123”); //第一種,參數(shù)是字符串
- BigInteger a=BigInteger.valueOf(123); //第二種,參數(shù)可以是int、long
BigDecimal 實(shí)現(xiàn)任意精度的浮點(diǎn)數(shù)運(yùn)算
BigDecimal 常用的構(gòu)造方法如下。
BigDecimal(double val):實(shí)例化時(shí)將雙精度型轉(zhuǎn)換為 BigDecimal 類型。
BigDecimal(String val):實(shí)例化時(shí)將字符串形式轉(zhuǎn)換為 BigDecimal 類型。
BigDecimal add(BigDecimal augend) // 加法操作 BigDecimal subtract(BigDecimal subtrahend) // 減法操作 BigDecimal multiply(BigDecimal multiplieand) // 乘法操作 BigDecimal divide(BigDecimal divisor,int scale,int roundingMode ) // 除法操作
char a='a';
char b='A';
char c='哈';
內(nèi)存大小
占兩個(gè)字節(jié),在C中是一個(gè)字節(jié),而且它可以存儲(chǔ)中文
這是C做不到的C言中使用 ASCII 表示字符, 而 Java 中使用 Unicode 表示字符. 因此一 個(gè)字符占用兩個(gè)字節(jié), 表示的字符種類更多, 包括中文
在Java中,char類型表示的是UTF-16的一個(gè)代碼單元,而不是Uncoide的字符 字符集和char的關(guān)系
?
布爾類型 booleanboolean b=true;
boolean b=false;
注意點(diǎn)
boolean只有兩個(gè)值,真就是true,假就是false
Java 的 boolean 類型和 int 不能相互轉(zhuǎn)換 , 不存在 1 表示 true, 0 表示 false 這樣的用法
如何將boolean變成0或者1
boolean類型在我們的官方文檔寫的是 It’s virtual machine dependent.// 由虛擬機(jī)自己實(shí)現(xiàn)
- 我們都知道,Java語言中有個(gè)boolean類型。每個(gè)boolean類型的變量中存儲(chǔ)的是一個(gè)true或者是false的邏輯值。那么存儲(chǔ)這個(gè)邏輯值,需要多大的空間呢?從理論上來講,存儲(chǔ)這個(gè)邏輯值只需要1個(gè)位(bit)就可以了,所以很多教科書上談到這個(gè)問題的時(shí)候,也說boolean類型的數(shù)據(jù)在內(nèi)存中只占1個(gè)位。
- 但是稍微有點(diǎn)計(jì)算機(jī)常識(shí)的人都知道:計(jì)算機(jī)完成尋址操作的時(shí)候,是以字節(jié)為最小單位進(jìn)行的。也就是說每次要讀取內(nèi)存中數(shù)據(jù)的時(shí)候,最小只能精確到1個(gè)字節(jié),不能單獨(dú)讀取某個(gè)位上的信息。如果boolean類型的變量的值只占1個(gè)位,計(jì)算機(jī)每次讀取到1個(gè)字節(jié)的信息,里面會(huì)包含8個(gè)boolean變量的值。計(jì)算機(jī)就不得不通過某種算法去確定這8個(gè)值中,哪一個(gè)才是我們要找的值。這樣做顯然非常不合理,因?yàn)橐瓿蛇@個(gè)“8選1”的操作又會(huì)增加運(yùn)算工作量。那么Java虛擬機(jī)到底是怎樣存儲(chǔ)boolean值呢?
- 在《虛擬機(jī)規(guī)范》中,對(duì)boolean類型的存儲(chǔ)有專門的解釋,文中說到:“雖然定義了boolean這種數(shù)據(jù)類型,但是只對(duì)它提供了非常有限的支持。在Java虛擬機(jī)中沒有任何供boolean值專用的字節(jié)碼指令,Java語言表達(dá)式所操作的boolean值,在編譯之后都使用Java虛擬機(jī)中的int數(shù)據(jù)類型來代替,而boolean數(shù)組將會(huì)被編碼成Java虛擬機(jī)的byte數(shù)組,(因此)每個(gè)boolean元素占8位”。
- 變成int類型,是因?yàn)槲覀兒芏嗟腃PU都是32位,這樣的存取效率是最高的
對(duì)于這種轉(zhuǎn)換但是無信息丟失的情況我們的隱式類型轉(zhuǎn)換是會(huì)自動(dòng)發(fā)生的
int a=10;
long b=20;//發(fā)生了隱式類型提升
long c=a+b;//發(fā)生了隱式類型提升
強(qiáng)制類型轉(zhuǎn)換對(duì)于轉(zhuǎn)換可能存儲(chǔ)精度損失的情況我們必須采用強(qiáng)制類型轉(zhuǎn)換
小類型 變量=(小類型) 大類型數(shù)值
int a = 0;
double b = 10.5;
a = (int)b;
int a = 10;
byte a=20;
byte b=256;//發(fā)生編譯錯(cuò)誤,因?yàn)閎yte的值位-128到127 所以需要強(qiáng)制類型轉(zhuǎn)換
boolean b = false;
b = (boolean)a; // 編譯出錯(cuò), 提示不兼容的類型
關(guān)于一個(gè)byte和byte的現(xiàn)象
byte a=20;
byte b=30;
byte c=a+b;//會(huì)發(fā)生編譯報(bào)錯(cuò)
可以寫成
final byte a=20;
final byte b=20;
byte c=a+b;
可以在賦值中使用二元運(yùn)算符,是一種很方便的簡(jiǎn)寫形式
int x=1;
x+=2;
x=x+2;
int x=1;
x+=3.5;//相當(dāng)于(int)(x+3.5)
自增/自減運(yùn)算符 ++ –int a = 10;
int b = ++a;
System.out.println(b);
int c = a++;
System.out.println(c);
結(jié)論:
關(guān)系運(yùn)算符主要有六個(gè):
== !=< ><= >=
int a = 10;
int b = 20;
System.out.println(a == b);
System.out.println(a != b);
System.out.println(a< b);
System.out.println(a >b);
System.out.println(a<= b);
System.out.println(a >= b);
注意: 關(guān)系運(yùn)算符的表達(dá)式返回值都是 boolean 類型
邏輯運(yùn)算符邏輯運(yùn)算符主要有三個(gè):
&& || !
注意: 邏輯運(yùn)算符的操作數(shù)(操作數(shù)往往是關(guān)系運(yùn)算符的結(jié)果)和返回值都是 boolean,如果操作數(shù)不是boolean,那么編譯不通過
邏輯與 &&
規(guī)則: 兩個(gè)操作數(shù)都為 true, 結(jié)果為 true, 否則結(jié)果為 false.
int a = 10;
int b = 20;
int c = 30;
System.out.println(a< b && b< c);
邏輯或 ||
規(guī)則: 兩個(gè)操作數(shù)都為 false, 結(jié)果為 false, 否則結(jié)果為 true
int a = 10;
int b = 20;
int c = 30;
System.out.println(a< b || b< c)
邏輯非 !
規(guī)則: 操作數(shù)為 true, 結(jié)果為 false; 操作數(shù)為 false, 結(jié)果為 true(這是個(gè)單目運(yùn)算符, 只有一個(gè)操作數(shù)).
int a = 10;
int b = 20;
System.out.println(!a< b);
&&與||都是短路運(yùn)算符&& 和 || 遵守短路求值的規(guī)則.
System.out.println(10 >20 && 10 / 0 == 0); // 打印 false
System.out.println(10< 20 || 10 / 0 == 0); // 打印 true
我們都知道, 計(jì)算 10 / 0 會(huì)導(dǎo)致程序拋出異常. 但是上面的代碼卻能正常運(yùn)行, 說明 10 / 0 并沒有真正被求值.
結(jié)論:
& 和 |
& 和 | 如果操作數(shù)為 boolean 的時(shí)候, 也表示邏輯運(yùn)算. 但是和 && 以及 || 相比, 它們不支持短路求值.
System.out.println(10 >20 & 10 / 0 == 0); // 程序拋出異常
System.out.println(10< 20 | 10 / 0 == 0); // 程序拋出異常
Java支持的三位運(yùn)算符
condition ? expression1 : expression2
int max=a>b?a:b; //返回a 和 b中較大的那個(gè)值
位運(yùn)算符java 中對(duì)數(shù)據(jù)的操作的最小單位不是字節(jié), 而是二進(jìn)制位.
位運(yùn)算符主要有四個(gè):
& | ~ ^
位操作表示 按二進(jìn)制位運(yùn)算. 計(jì)算機(jī)中都是使用二進(jìn)制來表示數(shù)據(jù)的(01構(gòu)成的序列), 按位運(yùn)算就是在按照二進(jìn)制位的每一位依次進(jìn)行計(jì)算
移位運(yùn)算符有三個(gè):
<< >>>>>
都是按照二進(jìn)制位來運(yùn)算.
int a = 0x10;
System.out.printf("%x\n", a<< 1);
// 運(yùn)行結(jié)果(注意, 是按十六進(jìn)制打印的)
20
int a = 0x10;
System.out.printf("%x\n", a >>1);
// 運(yùn)行結(jié)果(注意, 是按十六進(jìn)制打印的)
8
int b = 0xffff0000;
System.out.printf("%x\n", b >>1);
// 運(yùn)行結(jié)果(注意, 是按十六進(jìn)制打印的)
ffff8000
int a = 0xffffffff;
System.out.printf("%x\n", a >>>1);
// 運(yùn)行結(jié)果(注意, 是按十六進(jìn)制打印的)
7fffffff
關(guān)于移位大小的規(guī)定
先看一段代碼
System.out.println(1 + 2 * 3);
結(jié)果為 7, 說明先計(jì)算了 2*3 , 再計(jì)算 1+
另外一個(gè)例子
System.out.println(10< 20 && 20< 30);
此時(shí)明顯是先計(jì)算的 10< 20 和 20< 30, 再計(jì)算 &&. 否則 20 && 20 這樣的操作是語法上有誤的(&& 的操作數(shù)只能是boolean).運(yùn)算符之間是有優(yōu)先級(jí)的. 具體的規(guī)則我們不必記憶. 在可能存在歧義的代碼中加上括號(hào)即可.
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧