文章目錄
- 一、變數和型別
- 二、基本資料型別
- 1.整型變數
- 2.長整型
- 3.雙精度浮點型變數
- 4.單精度浮點型變數
- 5.字符型別變數
- 6.位元組型別變數
- 7.短整型變數
- 8.布爾型別變數
- 三、字串型別變數
- 四、轉義字符
- 五、變數的作用域
- 六、變數的命名規則
- 七、常量
- 八、常量與變數的本質區別及型別轉換
- 九、數值提升
- 十、運算子
- 1.基本四則運算子 + - * / %
- 2.增量賦值運算子 += -= *= /= %= 與自增/自減運算子 ++ --
- 3.關系運算子
- 4.邏輯運算子
- 5.位運算子與移位運算子及條件運算子
一、變數和型別
變數指的是程式運行時可變的量. 相當于開辟一塊記憶體空間來保存一些資料,
型別則是對變數的種類進行了劃分, 不同的型別的變數具有不同的特性,
我們經常討論的變數與記憶體的硬體設備密切相關,這里與馮諾依曼結構體系有著密切關系,

二、基本資料型別
1.整型變數
代碼示例:
int num = 10; // 定義一個整型變數
System.out.println(num) ;
注意事項:
- int表示變數的型別是一個整型,
- 變數名是變數的標識,后續都是通過這個名字來使用變數,
- Java 中 = 表示賦值(和數學不一樣),意思是給變數設定一個初始值,
- 初始化操作是可選的, 但是建議創建變數的時候都顯式初始化,如果沒有初始化變數就列印會編譯失敗,
- 最后不要忘記分號, 否則會編譯失敗,
- // 表示注釋. 注釋作為代碼的解釋說明部分, 不參與編譯運行,
在 Java 中, 一個 int 變數占 4 個位元組. 和作業系統沒有直接關系,因此int表示的資料的范圍是-2^31 -> 2^31-1,也就大概是 -21億 到 +21億,
使用以下代碼查看 Java 中的整型資料范圍:
System.out.println(Integer.MAX_VALUE); // int 的最大值
System.out.println(Integer.MIN_VALUE); // int 的最小值
//Integer是int的包裝類,后期會講到,
如果運算的結果超出了 int 的最大范圍, 就會出現溢位的情況:
int maxValue = Integer.MAX_VALUE;
System.out.println(maxValue+1);//列印的是-2^31的值
int minValue = Integer.MIN_VALUE;
System.out.println(minValue-1);//列印的是2^31-1的值
因此可以劃分為一個圈去理解與記憶:

21億這樣的數字對于當前的大資料時代來說, 是很容易超出的. 針對這種情況, 我們就需要使用更大范圍的資料型別來表示了,Java 中提供了 long 型別,
2.長整型
代碼示例:
long num = 10L; // 定義一個長整型變數, 初始值寫作 10l 也可以(小寫的 L, 不是數字1).
System.out.println(num);
注意事項:
- 基本語法格式和創建 int 變數基本一致, 只是把型別修改成 long ,
- 初始化設定的值為 10L , 表示一個長整型的數字. 10l 也可以,
- 使用 10 初始化也可以, 10 的型別是 int, 10L 的型別是 long, 使用 10 L 或者 10 l 更好一些,
Java 中 long 型別占 8 個位元組. 表示的資料范圍-2^63 -> 2^63-1,
使用以下代碼查看 Java 中的長整型資料范圍:
System.out.println(Long.MAX_VALUE);
System.out.println(Long.MIN_VALUE)
// 運行結果
9223372036854775807
-9223372036854775808
這個資料范圍遠超過 int 的表示范圍. 足夠絕大部分的工程場景使用,
3.雙精度浮點型變數
代碼示例:
double num = 1.0;
System.out.println(num)
在浮點型中有一些特殊例子:
示例1:
int a = 1;
int b = 2;
System.out.println(a / b);
// 執行結果
0
因為兩個int相除結果仍然為int型別,因此最終列印結果是0,若想最終列印的結果為0.5,需要其中的一個為float或double型別才可以,并且初始化為數字.0 或者兩者均為double型別 ,
示例2:
double num = 1.1;
System.out.println(num * num)
// 執行結果
1.2100000000000002
Java 中的 double 雖然也是 8 個位元組, 但是浮點數的記憶體布局和整數差別很大, 不能單純的用 2 ^ n 的形式表示資料范圍,
Java 的 double 型別的記憶體布局遵守 IEEE 754 標準(和C語言一樣), 嘗試使用有限的記憶體空間表示可能無限的小數, 勢必會存在一定的精度誤差,
4.單精度浮點型變數
float num = 1.0f; // 寫作 1.0F 也可以
System.out.println(num);
float 型別在 Java 中占四個位元組, 同樣遵守 IEEE 754 標準. 由于表示的資料精度范圍較小, 一般在工程上用到浮點數都優先考慮 double, 不太推薦使用 float ,如果初始化float時在數字后面沒有加上f,數字會默認為double型別,如果再放入float型別當中則編譯器會報錯,
5.字符型別變數
代碼示例:
char ch = 'A';
注意事項:
- Java 中使用 單引號 + 單個字母 的形式表示字符字面值.
- 計算機中的字符本質上是一個整數. 在 C 語言中使用 ASCII 表示字符, 而 Java 中使用 Unicode 表示字符. 因此一個字符占用兩個位元組, 表示的字符種類更多, 包括中文,
當列印一個漢字的時候,用char資料型別來存盤一個漢字是能夠放下的,并且列印的結果也是該漢字,
char ch = '呵';
System.out.println(ch);
6.位元組型別變數
代碼示例:
byte value = 0;
System.out.println(value);
注意事項:
- 位元組型別表示的也是整數,只占一個位元組, 表示范圍較小 ( -128 ~ +127 )
- 位元組型別和字符型別互不相干,位元組型別是用來存盤資料的,一般較少用,
7.短整型變數
代碼示例:
short value = 0;
System.out.println(value);
注意事項:
- short 占用 2 個位元組, 表示的資料范圍是 -32768 ~ +32767
- 這個表示范圍比較小, 一般不推薦使用,
8.布爾型別變數
代碼示例:
boolean value = true;
System.out.println(value);
注意事項:
- boolean 型別的變數只有兩種取值, true 表示真, false 表示假 ,
- Java 的 boolean 型別和 int 不能相互轉換, 不存在 1 表示 true, 0 表示 false 這樣的用法,因此boolean型別無法進行運算,
- boolean 型別有些 JVM 的實作是占 1 個位元組, 有些是占 1 個位元位, 這個沒有明確規定 ,
三、字串型別變數
把一些字符放到一起就構成了字串,
代碼示例:
String name = "zhangsan";
System.out.println(name);
注意事項:
- Java 使用 雙引號 + 若干字符 的方式表示字串字面值,
- 和上面的型別不同, String 不是基本型別, 而是參考型別(后面重點解釋),
- 字串中的一些特定的不太方便直接表示的字符需要進行轉義,
下面有幾個例子能夠很好地幫助理解String參考型別,
代碼示例1:
System.out.println("hello"+"world");//拼接
在字串中,‘+’代表的就是字串的拼接,并且一個數字+‘’,就會變為一個字串,
代碼示例2:
如何列印hello10+20呢?
System.out.println("hello"+10+20);
代碼示例3:
如何列印hello30呢?
System.out.println("hello"+(10+20));
代碼示例4:
如何列印30hello呢?
System.out.println(10+20+"hello");
代碼示例5:
如何列印10+20hello呢?
System.out.println(10+''+20+"hello");
四、轉義字符
轉義字符示例:
// 創建一個字串 My name is "張三"
String name = "My name is \"張三\"";
轉義字符有很多, 其中幾個比較常見的如下:
| 轉義字符 | 解釋 |
|---|---|
| \n | 換行 |
| \t | 水平制表符 |
| ’ | 單引號 |
| " | 雙引號 |
| \ | 反斜杠 |
在Java中需要記的轉義字符不多,只需要牢記這幾個轉義字符即可,
五、變數的作用域
也就是該變數能生效的范圍, 一般是變數定義所在的代碼塊 (大括號) ,
例子:
class Test {
public static void main(String[] args) {
{
int x = 10;
System.out.println(x); // 編譯通過;
}
System.out.println(x); // 編譯失敗, 找不到變數 x.
}
}
六、變數的命名規則
硬性指標:
- 一個變數名只能包含數字, 字母, 下劃線 ,
- 數字不能開頭,
- 變數名是大小寫敏感的. 即 num 和 Num 是兩個不同的變數,
注意: 雖然語法上也允許使用中文/美元符($)命名變數, 但是 強烈 不推薦這樣做,
軟性指標:
- 變數命名要具有描述性, 見名知意,
- 變數名不宜使用拼音(但是不絕對) ,
- 變數名的詞性推薦使用名詞,
- 變數命名推薦 小駝峰命名法, 當一個變數名由多個單詞構成的時候, 除了第一個單詞之外, 其他單詞首字母都大寫,
小駝峰命名示例:
int maxValue = 100;
String studentName = "張三";
七、常量
上面討論的都是各種規則的變數, 每種型別的變數也對應著一種相同型別的常量.
常量指的是運行時型別不能發生改變.
常量主要有以下兩種體現形式:
- 字面值常量
10 // int 字面值常量(十進制)
010 // int 字面值常量(八進制) 由數字 0 開頭. 010 也就是十進制的 8
0x10 // int 字面值常量(十六進制) 由數字 0x 開頭. 0x10 也就是十進制的 16
10L // long 字面值常量. 也可以寫作 10l (小寫的L)
1.0 // double 字面值常量. 也可以寫作 1.0d 或者 1.0D
1.5e2 // double 字面值常量. 科學計數法表示. 相當于 1.5 * 10^2
1.0f // float 字面值常量, 也可以寫作 1.0F
true // boolen 字面值常量, 同樣的還有 false
'a' // char 字面值常量, 單引號中只能有一個字符
"abc" // String 字面值常量, 雙引號中可以有多個字符.
- final 關鍵字修飾的常量
final int a = 10;
a = 20; // 編譯出錯. 提示 無法為最終變數a分配值
常量不能在程式運行程序中發生修改,
八、常量與變數的本質區別及型別轉換
常量在程式運行的程序當中是不能夠被修改的,并且在程式編譯的時候,就已經確定其值為什么,常量只能初始化1次,而變數在程式運行的時候,是可以改變的量,在程式運行的時候,才知道變數當中放入的值是多少,
因此下面有個這樣的代碼:
int 和 long/double 相互賦值
int a = 10;
long b = a ;
//可行
long a = 12 ;
int b = a ;
//err
為什么將long a = 12的值賦值給int b時會報錯呢?因為變數在程式運行時才知道里面放的值是多少,而編譯的程序中還無法得知,因此long是8個位元組,int是4個位元組,8個位元組的long放入4個位元組的int當中一定會報錯,
int a = 10;
double b = 1.0;
a = b; // 編譯出錯, 提示可能會損失精度.
b = a; // 編譯通過
結論: 不同數字型別的變數之間賦值, 表示范圍更小的型別能隱式轉換成范圍較大的型別, 反之則不行,
int 和 boolean 相互賦值:
int a = 10;
boolean b = true;
b = a; // 編譯出錯, 提示不兼容的型別
a = b; // 編譯出錯, 提示不兼容的型別
結論: int 和 boolean 是毫不相干的兩種型別, 不能相互賦值,
int 字面值常量 給 byte 賦值:
byte a = 100; // 編譯通過
byte b = 256; // 編譯報錯, 提示 從int轉換到byte可能會有損失
注意: byte 表示的資料范圍是 -128 -> +127, 256 已經超過范圍, 而 100 還在范圍之內.
結論: 使用字面值常量賦值的時候, Java 會自動進行一些檢查校驗, 判定賦值是否合理,
使用強制型別轉換:
int a = 0;
double b = 10.5;
a = (int)b;
int a = 10;
boolean b = false;
b = (boolean)a; // 編譯出錯, 提示不兼容的型別
結論:
- 使用 (型別) 的方式可以將 double 型別強制轉成 int,但是強制型別轉換可能會導致精度丟失. 如剛才的例子中, 賦值之后, 10.5 就變成 10 了, 小數點后面的部分被忽略,
- 強制型別轉換不是一定能成功, 互不相干的型別之間無法強轉,
short字面值常量給byte并強轉:
short a =128;
byte b =(byte) a;
結果變數b的值為-128,是什么原因呢?因為128的二進制為1000 0000(short是2個位元組,在1前面還要補8個0) ,而byte為1個位元組,因此存入b中的直接就為1000 0000,而最高位為符號位,1代表負數,并且1000 0000為-128 ,
int 和 String 之間的相互轉換:
1.int 轉成 String
int num = 10;
// 方法1
String str1 = num + ""; //不建議
// 方法2
String str2 = String.valueOf(num);
最終將整型型別的10轉換為字串型別’10’ ,
2.String轉換為int
String str = "100";
int num = Integer.valueOf(str);
最終將字串型別的資料轉換為整型,
九、數值提升
1.int 和 long 混合運算
int a = 10;
long b = 20;
int c = a + b; // 編譯出錯, 提示將 long 轉成 int 會丟失精度
long d = a + b; // 編譯通過.
結論: 當 int 和 long 混合運算的時候, int 會提升成 long, 得到的結果仍然是 long 型別, 需要使用 long 型別的變數來
接收結果. 如果非要用 int 來接收結果, 就需要使用強制型別轉換,
2.byte 和 byte 的運算
byte a = 10;
byte b = 20;
byte c = a + b;
System.out.println(c);
// 編譯報錯
Test.java:5: 錯誤: 不兼容的型別: 從int轉換到byte可能會有損失
結論: byte 和 byte 都是相同型別, 但是出現編譯報錯. 原因是, 雖然 a 和 b 都是 byte, 但是計算 a + b 會先將 a 和 b 都
提升成 int, 再進行計算, 得到的結果也是 int, 這是賦給 c, 就會出現上述錯誤,
需要注意的是:以下代碼并不會報錯!
byte c = 10+20;
System.out.println(c);
這是什么原因呢?
就是因為在編譯程序中,已經算好了10+20=30,并且賦給了c,
由于計算機的 CPU 通常是按照 4 個位元組為單位從記憶體中讀寫資料. 為了硬體上實作方便, 諸如 byte 和 short 這種低于4 個位元組的型別, 會先提升成 int, 再參與計算,
正確的寫法:
byte a = 10;
byte b = 20;
byte c = (byte)(a + b);
System.out.println(c);
int 和 double 的運算
int a = 10 ;
int b = 3 ;
double c = a/b ;
System.out.println(c);//列印結果3.0
int d = 10 ;
double e = 3 ;
double f = d/e ;
System.out.println(f);//列印結果3.3333333333333335
第一段代碼中列印結果為3.0的原因是因為a與b都為int型別,其運算的結果仍是int型別,只不過存入了型別為double的c變數當中,結果為3.0;第二段代碼中因為是int與double型別的運算,int要進行數值提升為double,因此d/e的運算結果型別就為double型別,放入了double型別變數f中,列印結果為3.3333333333333335 ,
十、運算子
總體跟C語言運算子差不多,只列舉幾個Java中特有的運算子及它們的特點,
1.基本四則運算子 + - * / %
0 不能作為除數,
int a = 1;
int b = 0;
System.out.println(a / b)
// 運行結果(報錯)
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Test.main(Test.java:5)
% 表示取余, 不僅僅可以對 int 求模, 也能對 double 來求模,
System.out.println(11.5 % 2.0);
// 運行結果
1.5
2.增量賦值運算子 += -= *= /= %= 與自增/自減運算子 ++ –
增量賦值運算子 += -= *= /= %=
int a = 10;
a += 1; // 等價于 a = a + 1
System.out.println(a);
有個需要注意的點:
short a = 10 ;
short b = a+10;
System.out.println(b);//error
short c = 10 ;
c+=10;
System.out.println(c);
第一段代碼報錯的原因是在a+10的程序當中a要進行整型提升,最后存入short型別中就報錯,第二段代碼沒有報錯是因為c+=10的程序中程式會幫助我們自動進行強制型別轉換,
自增/自減運算子 ++ –
int a = 10;
int b = ++a;
System.out.println(b); //列印結果為11
int c = a++;
System.out.println(c);//列印結果為10
需要注意的是:
int a = 10;
++a;
System.out.println(a); //列印結果為11
int c = 10;
c++;
System.out.println(c);//列印結果為11
因為此處沒有需要被使用的情況,到列印時就直接將其自增后的值列印,
**結論:
- 如果不取自增運算的運算式的回傳值, 則前置自增和后置自增沒有區別,
- 如果取運算式的回傳值, 則前置自增的回傳值是自增之后的值, 后置自增的回傳值是自增之前的值,**
3.關系運算子
關系運算子主要有六個:== != < > <= >=
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);
注意: 關系運算子的運算式回傳值都是 boolean 型別,
4.邏輯運算子
邏輯運算子主要有三個:&& || ! ,因為這三個運算子在C語言中已經運用地非常熟練了,因此此處直接略過,只講&&與||的短路求值,
&&和||的短路求值:
System.out.println(10 > 20 && 10 / 0 == 0); // 列印 false
System.out.println(10 < 20 || 10 / 0 == 0); // 列印 true
上面已經說過, 計算 10 / 0 會導致程式拋出例外. 但是上面的代碼卻能正常運行, 說明 10 / 0 并沒有真正被求值 ,
結論:
- 對于 && , 如果左側運算式值為 false, 則運算式的整體的值一定是 false, 無需計算右側運算式,
- 對于 ||, 如果左側運算式值為 true, 則運算式的整體的值一定是 true, 無需計算右側運算式,
5.位運算子與移位運算子及條件運算子
位運算子有四個:& | ~ ^ ,位操作表示 按二進制位運算. 計算機中都是使用二進制來表示資料的(01構成的序列), 按位運算就是在按照二進制位的每一位依次進行計算,在C語言中運算地也很多,因此不再介紹,
移位運算子有三個:<< >> >>> ,都是按照二進制位來運算,相較C語言來說,多了>>>運算子,因此此處只介紹它,
運算子>>>被稱為無符號右移 :最右側位不要了, 最左側補 0,
int a = 0xffffffff;
System.out.printf("%x\n", a >>> 1);
// 運行結果(注意, 是按十六進制列印的)
7fffffff
注意:
- 左移 1 位, 相當于原數字 * 2. 左移 N 位, 相當于原數字 * 2 的N次方,
- 右移 1 位, 相當于原數字 / 2. 右移 N 位, 相當于原數字 / 2 的N次方,
- 由于計算機計算移位效率高于計算乘除, 當某個代碼正好乘除 2 的N次方的時候可以用移位運算代替,
- 移動負數位或者移位位數過大都沒有意義,
條件運算子只有一個:運算式1 ? 運算式2 : 運算式3
當 運算式1 的值為 true 時, 整個運算式的值為 運算式2 的值; 當 運算式1 的值為 false 時, 整個運算式的值為 運算式3 的值,條件運算子也是 Java 中唯一的一個 三目運算子, 是條件判斷陳述句的簡化寫法,
// 求兩個整數的最大值
int a = 10;
int b = 20;
int max = a > b ? a : b;
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/316585.html
標籤:java
