1.變量
變量概述
什么是變量?變量是一個內存中的小盒子(小容器),容器是什么?生活中也有很多容器,例如水杯是容器,用來裝載水;你家里的大衣櫃是容器,用來裝載衣褲;飯盒是容器,用來裝載飯菜。那么變量是裝載什么的呢?答案是數據!結論:變量是內存中裝載數據的小盒子,你只能用它來存數據和取數據。
計算機存儲單元
變量是內存中的小容器,用來存儲數據。那么計算機內存是怎么存儲數據的呢?無論是內存還是硬盤,計算機存儲設備的最小信息單元叫“位(bit)”,我們又稱之為“比特位”,通常用小寫的字母b表示。而計算機最小的存儲單元叫“字節(byte)”,通常用大寫字母B表示,字節是由連續的8個位組成。
當程序需要使用存儲空間時,操作系統最小會分派給程序1個字節,而不是1個位。你可能會說,如果程序只需要1個位的空間,系統分派不能只分派1個位嗎?答案是不能!這就像你只需要1支煙,你到商店去買煙,商店分派的最小單元是1盒(20支),他不可能賣給你1支煙。
你可能會想,1個字節(8位)可以存儲很大的數值了,1位最大是9那么8位最大值為99999999。你錯了,因為計算機是采用二進行存儲的,而不是我們生活中常用的十進制。所以1個字節存儲的最大數據是11111111的二進制數。
除了字節外還有一些常用的存儲單位,大家可能比較熟悉,我們一起來看看:
1B(字節) = 8bit
1KB = 1024B
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
1PB = 1024TB
基本類型之4類8種
大衣櫃不能用來裝載水,水杯也不能用來裝載衣褲。這說明不同的容器裝載不同的物品。變量也是如此,在創建變量時需要指定變量的數據類型,例如整型變量、浮點型變量等等。結論:變量必須要有明確的類型,什么類型的變量裝載什么類型的數據。
水杯是用來裝水的,那么水杯能裝多少水呢?一噸?我們知道水杯在創建時不只確定了要裝載的是水(數據類型),而且還確定了能裝多少水(數據類型的具體種類)。變量也是如此,需要指定變量能裝載什么類型的數據,同時也要指定變量能裝載多大的數據。
Java中基本類型一共4類,把這4類展開后共8種基本類型。我們今后編寫程序時使用的是這8種基本類型而不是4類,這8種基本類型指定了范圍。
| 四類 |
八種 |
字節數 |
數據表示范圍 |
| 整型 |
byte |
1 |
-128~127 |
| short |
2 |
-32768~32767 |
|
| int |
4 |
-2147483648~2147483648 |
|
| long |
8 |
-263~263-1 |
|
| 浮點型 |
float |
4 |
-3.403E38~3.403E38 |
| double |
8 |
-1.798E308~1.798E308 |
|
| 字符型 |
char |
2 |
表示一個字符,如('a','A','0','家') |
| 布爾型 |
boolean |
1 |
只有兩個值true與false |
常量與類型
前面我們說過100是整數常量,但它是byte、short、int、long中的哪一種呢?下面我們來聊聊這一常量類型的問題。
整數常量可以根據所在范圍來確定類型,例如100在-128~127之間,所以他是byte類型;500在-32768~32767之間,所以它是short類型;100000在-2147483648~2147483648之間,所以它是int類型。java中默認的整數類型是int類型
你可能會認為12345678901在-263~263-1之間,所以它是long類型。注意了,這是錯誤的!!!在Java中整數常量如果不在-2147483648~2147483648之間就必須添加“L”后綴(小寫的也可以,但建議使用大寫),在-2147483648~2147483648之間的也可以添加“L”后綴。也就是說12345678901不在-2147483648~2147483648之間,所以它在Java中是錯誤的常量,你必須這樣寫:12345678901L,這才是正確的常量。所以添加了“L”后綴的整數常量都是long類型的,例如:100L、12345678901L都是long類型的常量。
浮點類型的常量也可使用后綴,在Java中所有沒有后綴以及使用“D”后綴(小寫也可以,但建議使用大寫)的小數都是double類型;float類型常量必須添加“F”后綴(小寫也可以,但建議使用大寫)java中默認的浮點類型是double類型
- 3.14沒有后綴,所以它是double類型;
- 5.28D為double類型;
- 1.26F為float類型。
定義變量(創建變量)
定義變量的語法格式:
數據類型 變量名 = 數據值; int a = 100;
其中int是數據類型,指定了變量只能存儲整數,而且指定了存儲范圍為-2147483648~2147483648。
其中a表示變量名,變量名是標識符,這說明只要是合法的標識符都可以用來做變量名。在程序中可以通過變量名來操作變量(內存中的小盒子)。
其中“=100”是給變量賦值,即向a變量中寫入100(變量是個小盒子,現在小盒子中保存的是100)。注意,給變量賦的值一定要與類型符合,也就是說int類型只能存儲整數,而且必須是在-2147483648~2147483648范圍內的整數。100滿足了這兩個條件,所以是正確的。
/* 變量定義格式: 數據類型 變量名 = 變量值; */ public class Variable { public static void main(String[] args) { int a = 10; double b = 3.14; char c = 'z'; String s = "i love java"; a = 20; System.out.println(a); } }
變量使用的注意事項:
- 變量定義后可以不賦值,使用時再賦值。不賦值不能使用。
public static void main(String[] args) { int x; x = 20; //為x賦值20 System.out.println(x);//讀取x變量中的值,再打印 }
- 變量使用時有作用域的限制。
public static void main(String[] args) { int x = 20; { int y = 20; } System.out.println(x);//讀取x變量中的值,再打印 System.out.println(y);//讀取y變量中的值失敗,失敗原因,找不到y變量,因為超出了y變量作用范圍,所以不能使用y變量 }
- 變量不可以重復定義。
public static void main(String[] args){ int x = 10; double x = 5.5;//編譯失敗,變量重復定義 }
數據類型轉換
不同類型的變量是否可以在一起運算呢?答案是可以的,但要先進行類型轉換再運算。下面我們來學習一下類型轉換。
其實,我們所學習的數據,它的表示方式是可以靈活多變的,比如把小數轉換成整數的操作
轉換的過程中,數據遵循一個原則:
范圍小的數據類型值(如byte),可以直接轉換為范圍大的數據類型值(如int);
范圍大的數據類型值(如int),不可以直接轉換為范圍小的數據類型值(如byte)
那么,大家還記得每種類型表示數據的范圍嗎?忘記了不要緊,我來告訴大家,將各種數據類型按照數據范圍從小到大依次列出:
byte -> short -> int -> long -> float -> double
關於數據類型轉換有兩種方式,我們來學習一下:
自動類型轉換
表示范圍小的數據類型轉換成范圍大的數據類型,這種方式稱為自動類型轉換
自動類型轉換格式:
范圍大的數據類型 變量 = 范圍小的數據類型值;
如:
double d = 1000;或 int i = 100; double d2 = i;
強制類型轉換
表示范圍大的數據類型轉換成范圍小的數據類型,這種方式稱為強制類型轉換
強制類型轉換格式:
范圍小的數據類型 變量 = (范圍小的數據類型) 范圍大的數據類型值;
如:
int i = (int)6.718; //i的值為6 或 double d = 3.14; int i2 = (int)d; //i2的值為3
2.運算符
計算機的最基本用途之一就是執行數學運算,作為一門計算機語言,Java也提供了一套豐富的運算符來操縱變量。我們可以把運算符分成以下幾組:
- 算術運算符
- 關系運算符
- 位運算符
- 邏輯運算符
- 賦值運算符
- 其他運算符
| 操作符 | 描述 | 例子 |
|---|---|---|
| + | 加法 - 相加運算符兩側的值 | A + B 等於 30 |
| - | 減法 - 左操作數減去右操作數 | A – B 等於 -10 |
| * | 乘法 - 相乘操作符兩側的值 | A * B等於200 |
| / | 除法 - 左操作數除以右操作數 | B / A等於2 |
| % | 取余 - 左操作數除以右操作數的余數 | B%A等於0 |
| ++ | 自增: 操作數的值增加1 | B++ 或 ++B 等於 21(區別詳見下文) |
| -- | 自減: 操作數的值減少1 | B-- 或 --B 等於 19(區別詳見下文) |
我們在使用算術運算符時,記得要注意下列事項:
- 加法運算符在連接字符串時要注意,只有直接與字符串相加才會轉成字符串。
- 除法“/”當兩邊為整數時,取整數部分,舍余數。當其中一邊為浮點型時,按正常規則相除。
- “%”為整除取余符號,小數取余沒有意義。結果符號與被取余符號相同。
- 整數做被除數,0不能做除數,否則報錯。
演示(結果可以自己敲一下)
/* * 算術運算符 */ public class OperatorDemo1 { public static void main(String[] args) { /* * 常量使用算數運算符 */ System.out.println(10+20); /* * 變量使用算數運算符 */ int x = 10; int y = 20; //"+"作為加法運算使用 int z = x + y; //"+"作為連接字符串使用 System.out.println("x="+x); System.out.println("y="+y); System.out.println("z="+z); } }
算數運算符++、--的使用
算數運算符在前面我們已經學習過了,這里進行一些補充。
在一般情況下,算數運算符不會改變參與計算的變量值。而是在原有變量值不變的情況下,計算出新的值。但是有些操作符會改變參與計算的變量的值,比如++,--。
看下面的代碼
int a = 3; int b = 3; a++; b--; System.out.println(a); System.out.println(b);
上面代碼的輸出結果a值為4,b值為2;
這說明a的原有值發生了改變,在原有值的基礎上自增1;b的原有值也發生了改變,在原有值的基礎上自減1;
- ++運算符,會在原有值的基礎上自增1;
- --運算符,會在原有值的基礎上自減1。
在看下面代碼:
int a = 3; int b = 3; ++a; --b; System.out.println(a); System.out.println(b);
上面代碼的輸出結果a值為4,b值為2;
這說明++,--運算符單獨使用,不參與運算操作時,運算符前后位置導致的運算結果是一致的。
接下來,介紹下++,--運算符參與運算操作時,發生了怎樣的變化,我們來看一段代碼:
int a = 3; int b; b = a++ + 10; System.out.println(a); System.out.println(b);
上面代碼的輸出結果a值為4,b值為13;
這里我要強調一下了,當++,--運算符參與運算操作時,后置++,--的作用:
- ++,--運算符后置時,先使用變量a原有值參與運算操作,運算操作完成后,變量a的值自增1或者自減1;
再介紹下++,--運算符前置時,參與運算操作的變化,我們來看一段代碼:
int a = 3; int b; b = ++a + 10; System.out.println(a); System.out.println(b);
上面代碼的輸出結果a值為4,b值為14;
- ++,--運算符前置時,先將變量a的值自增1或者自減1,然后使用更新后的新值參與運算操作。
賦值運算符
| 運算符 |
運算規則 |
范例 |
結果 |
| = |
賦值 |
int a=2 |
2 |
| += |
加后賦值 |
int a=2,a+=2 |
4 |
| -= |
減后賦值 |
int a=2,a-=2 |
0 |
| *= |
乘后賦值 |
int a=2,a*=2 |
4 |
| /= |
整除后賦值 |
int a=2,a/=2 |
1 |
| %= |
取模后賦值 |
int a=2,a%=2 |
0 |
注意:諸如+=這樣形式的賦值運算符,會將結果自動強轉成等號左邊的數據類型。
寫一個代碼,我們看一下賦值運算符的使用
/* * 賦值運算符 * +=, -=, *=, /=, %= : * 上面的運算符作用:將等號左右兩邊計算,會將結果自動強轉成等號左邊的數據類型,再賦值給等號左邊的 * 注意:賦值運算符左邊必須是變量 */ public class OperatorDemo2 { public static void main(String[] args) { byte x = 10; x += 20;// 相當於 x = (byte)(x+20); System.out.println(x); } }
結果為30;
比較運算符
比較運算符,又叫關系運算符,它是用來判斷兩個操作數的大小關系及是否相等關系的,結果是布爾值true或者false。
| 運算符 |
運算規則 |
范例 |
結果 |
| == |
相等於 |
4==3 |
False |
| != |
不等於 |
4!=3 |
True |
| < |
小於 |
4<3 |
False |
| > |
大於 |
4>3 |
True |
| <= |
小於等於 |
4<=3 |
False |
| >= |
大於等於 |
4>=3 |
True |
這里需要注意一下:
賦值運算符的 = 符號與比較運算符的 == 符號是有區別的,如下:
- 賦值運算符的 = 符號,是用來將 = 符號右邊的值,賦值給 = 符號左邊的變量;
- 比較運算符的 == 符號,是用來判斷 == 符號 左右變量的值是否相等的。
我們通過下面的一段代碼,我們演示一下這個注意事項:
int a = 3; int b = 4; System.out.println( a=b ); System.out.println( a==b );
上面代碼輸出的結果第一個值為4,第二個值為false。
邏輯運算符
邏輯運算符,它是用於布爾值進行運算的,運算的最終結果為布爾值true或false。
| 運算符 |
運算規則 |
范例 |
結果 |
| & |
與 |
false&true |
False |
| | |
或 |
false|true |
True |
| ^ |
異或 |
true^flase |
True |
| ! |
非 |
!true |
Flase |
| && |
短路與 |
false&&true |
False |
| || |
短路或 |
false||true |
True |
看完圖后,我們來看一下邏輯運算符的常規使用方式:
- l 邏輯運算符通常連接兩個其他表達式計算后的布爾值結果
- l 當使用短路與或者短路或時,只要能判斷出結果則后邊的部分就不再判斷。
我們通過代碼演示一下:
boolean b = 100>10; boolean b2 = false; System.out.println(b&&b2); // 打印結果為 false System.out.println(b||b2); //打印結果為 true System.out.println(!b2); //打印結果為 true System.out.println(b && 100>10); //打印結果為 true,本行結果的計算方式稍后講解運算符優先級時解答
好了,我們來總結一下運算符的結果規律吧:
- 短路與&&:參與運算的兩邊數據,有false,則運算結果為false;
- 短路或||:參與運算的兩邊數據,有true,則運算結果為true;
- 邏輯非! : 參與運算的數據,原先是true則變成false,原先是false則變成true。
三元運算符
接下來我們要學習的三元運算符與之前的運算符不同。之前學習的均為一元或者二元運算符。元即參與運算的數據。
格式:
(條件表達式)?表達式1:表達式2;
表達式:通俗的說,即通過使用運算符將操作數聯系起來的式子,例如:
3+2,使用算數運算符將操作數聯系起來,這種情況,我們稱為算數表達式。
3>2,使用比較運算符(也稱為條件運算符)將操作數聯系起來,這種情況,我們稱為條件表達式。
其他表達式,不再一一舉例。
三元運算符運算規則:
先判斷條件表達式的值,若為true,運算結果為表達式1;若為false,運算結果為表達式2。
方式一: System.out.println( 3>2 ? “正確” : “錯誤” ); // 三元運算符運算后的結果為true,運算結果為表達式1的值“正確”,然后將結果“正確”,在控制台輸出打印 方式二: int a = 3; int b = 4; String result = (a==b) ? “相等” : “不相等”; //三元運算符運算后的結果為false,運算結果為表達式2的值“不相等”,然后將結果賦值給了變量result 方式三: int n = (3>2 && 4>6) ? 100 : 200; //三元運算符運算后的結果為false,運算結果為表達式2的值200,然后將結果200賦值給了變量n
運算符優先級
在學習運算符的過程中,我們發現,當多個運算符一起使用的時候,容易出現不清晰先后運算順序的問題,那么,在這里,我們來學習下,運算符之間的運算優先級。
下圖是每種運算符的優先級,按照運算先后順序排序(優先級相同的情況下,按照從左到右的順序依次運算)
| 優先級 |
描述 |
運算符 |
| 1 |
括號 |
()、[] |
| 2 |
正負號 |
+、- |
| 3 |
自增自減,非 |
++、--、! |
| 4 |
乘除,取余 |
*、/、% |
| 5 |
加減 |
+、- |
| 6 |
移位運算 |
<<、>>、>>> |
| 7 |
大小關系 |
>、>=、<、<= |
| 8 |
相等關系 |
==、!= |
| 9 |
按位與 |
& |
| 10 |
按位異或 |
^ |
| 11 |
按位或 |
| |
| 12 |
邏輯與 |
&& |
| 13 |
邏輯或 |
|| |
| 14 |
條件運算 |
?: |
| 15 |
賦值運算 |
=、+=、-=、*=、/=、%= |
| 16 |
位賦值運算 |
&=、|=、<<=、>>=、>>>= |
優先級順序看完了,我們來通過代碼,加強一下:
int n = 3>4 ? 100 : 200;
這行的代碼運算執行順序我們來寫一下:
1.執行 3>4操作,得到布爾類型false的結果
2.通過結果false,將對應的表達式2的結果200,作為運算的最終結果
3.把200 賦值給變量n
接下來,我們看一個比較復雜的代碼
int a = 5; int b = 3; int c = 1; int n2 = (a>b && b>c) ? (c++) : (++c);
這段代碼運算執行順序我們也寫一下:
1.小括號優先級高,我們先運算第一組小括號中的代碼
1.1. 比較運算符”>” 優先級大於 邏輯運算符”&&”
先執行 a>b,得到結果true;
再執行 b>c,得到結果true;
最后執行 a>b的結果 && b>c的結果,即 true && true, 結果為true
2.三元運算符中的條件判斷結果為true,返回表達式1的結果 c++
先將變量c的原有值賦值給變量n2,即n2值為1;
再將變量c的值自增1,更新為2。
結果為1;
參考:http://www.runoob.com/java/java-operators.html
