這系列博文主要是將自己之前學習的一些java基礎內容進行歸納與總結。
八大基本數據類型
基本數據類型 | 默認值 | 包裝類 | 佔用空間 | 取值範圍 | 緩存區間 |
---|---|---|---|---|---|
byte | 0 | Byte | 1 Byte | -128 ~ 127 | -128~127 |
short | 0 | Short | 2 Byte | -2^15 ~ 2^15-1 | -128~127 |
int | 0 | Integer | 4 Byte | -2^31 ~ 2^31-1 | -128~127 |
long | 0 | Long | 8 Byte | -2^63 ~ 2^63-1 | -128~127 |
float | 0.0 | Float | 4 Byte | -2^128 ~ 2^128 | 無 |
double | 0.0 | Double | 8 Byte | -2^1024 ~ 2^1024 | 無 |
boolean | false | Boolean | 1 Byte/4Byte | false/true | 無 |
char | \u0000 | Character | 2 Byte | 0 ~ 65535 | 0~127 |
特殊的幾個數據類型寫法:
// long類型需要加 l / L(推薦用大寫區分)
long l = 1L;
// float類型需要加 f / F
float f = 0.1f;
// char類型是由單引號括起來的單個字符
char c = 'a';
基本數據類型自動向上轉型關係:
byte,short,char → int → long → float → double
byte,short,char三者之間只有byte可以轉爲short
基本數據類型在作爲類成員時纔會有默認值,作爲局部變量如果沒有進行顯式初始化,在使用的時候會報編譯時異常
多種基本數據類型混合運算時會先轉換成容量最大的數據類型再進行運算
char類型在參與算術運算時會轉換爲ASCII碼對應的值
System.out.println('*' + '\t' + '*'); // 93
System.out.println("*" + '\t' + '*'); // * *
byte,short,char三者參與運算時會默認轉換爲int類型再運算
short s, s2 = 1;
short s3 = s + s2; // 編譯異常,需要用int接收
運算符
算術運算符
+
、-
、*
、/
、%
對於除運算,除數與被除數都爲整型時,如果除不盡會直接捨棄小數取整
int i = 1 / 5.0; // 編譯異常,需要強轉爲double
int ii = 1 / 2; // 0 0.5會直接取整
對於模運算,兩邊都應爲整型,要不結果很奇怪,負數的模運算結果看左邊
double d = 10 % -5.1; // 4.9
double dd = -10 % 5.1; // -4.9
應用:
求模運算結果都比模數小(控制大小)
任何數模以2不是0就是1(開關控制)
賦值運算符
=
、+=
、-=
、/=
、%=
、++
、--
自增(自減)符號在前先自增(自減)再運算,自增(自減)符號在後先運算後自增(自減) 例:
int a = 0;
int b = 1;
System.out.println(++a + b++); // 2
System.out.println(a); // 1
System.out.println(b); // 2
+=
、-=
、/=
、%=
會自動向下轉型,存在丟失精度的風險 例:
byte b = 2;
b += 126
system.out.pritln(b) // -128 byte範圍是-128~127
比較運算符
==
、!=
、>
、<
、>=
、<=
邏輯運算符
&&
(邏輯與,若左邊爲false則右邊不進行運算,同真才爲true)
||
(邏輯或,若左邊爲true則右邊不進行運算,有一個爲真即爲true)
!
(非運算) !true = false
位運算符
&
(按位與,兩邊都進行運算,除了做邏輯運算,還能做算術運算) 例: 6&2 = 2,化二進制有假(0)爲假
|
(按位或,兩邊都進行運算,除了做邏輯運算,還能做算術運算) 例:6|3 = 7,化二進制有真(1)爲真
^
(異或,除了做邏輯運算,還能做算術運算)
例:6^3 = 5,化二進制相同爲假不同爲真
ps: 一個數異或另一個數兩次結果還是這個數
<<
(左移,乘2的冪運算,空位補0) 例: 5<<3 = 5*2^3 = 40
>>
(有符號整數右移,算術右移,除2的冪運算,最高位是什麼空位就補什麼) 例:5>>3 = 5/2^3 = 0
>>>
(無符號整數右移,邏輯右移,無論最高位是什麼空位都補0)
~
(取反,一個數取反即相反數-1) 例: ~n = (-n) - 1
三元運算符
條件表達式?表達式1:表達式2,條件表達式爲true則執行表達式1,否則執行表達式2
int x = a > b ? a : b; // 取兩位數中的較大值
三元運算符的類型轉換規則:
-
若兩個表達式類型相同,則返回值類型爲該類型
-
若兩個表達式類型不同,且不能進行轉化,則返回的是他們最接近的父類類型
boolean condition = false; Serializable serializable = condition ? "" : 1.0; AbstractList<Object> abstractList = condition ? new ArrayList<>() : new LinkedList<>();
-
若其中一個表達式X是
char
,byte
,short
類型(或他們的包裝類),另一個Y是int
類型,若在編譯器就能判斷出Y在X的範圍內,則返回類型爲Y,反之則返回X。如果不是這幾種則會發生自動向上轉型boolean condition = false; char c; byte b; short s; int i; // 98自動轉爲char char r = condition ? c : 98; // 98自動轉爲byte byte r2 = condition ? b : 98; // 98自動轉爲short short r3 = condition ? s : 98; // 128超出了byte的範圍,b自動轉爲int int r4 = condition ? b : 128; // 前面已經聲明瞭i爲int,則不會自動轉化爲byte int r5 = condition ? b : i; // float自動向上轉型爲double double r6 = condition ? 50f : 100d;
-
若遇到表達式爲包裝類型,則會先轉化爲基本數據類型,然後按照基本數據類型的自動轉化規則進行轉化,返回值爲優先級最高的基本數據類型
boolean condition = false; Character c = null; Integer a = 127; // c和a都會調用.valueOf()方法轉爲基本數據類型,所以返回int類型 // 但是運行時c爲null調用valueOf會報NullPointerException int i = condition ? c : a;
這點大多數人會忽略,所以慎用三元運算符
運算符優先級
運算符 | 結合性 |
---|---|
[ ] . ( ) (方法調用) | 從左向右 |
! ~ ++ – +(正) -(負) | 從右向左 |
* / % | 從左向右 |
+ - | 從左向右 |
<< >> >>> | 從左向右 |
< <= > >= instanceof | 從左向右 |
== != | 從左向右 |
& | 從左向右 |
^ | 從左向右 |
| | 從左向右 |
&& | 從左向右 |
|| | 從左向右 |
?: | 從右向左 |
= | 從右向左 |
趣味題
不使用第三方變量,交換兩個變量的值
int a = 0;
int b = 1;
// 解一
a = a + b;
b = a - b; // b = a + b - b
a = a - b; // a = a + b - a
// 解二
a = a ^ b;
b = a ^ b; // b = a ^ b ^ b
a = a ^ b; // a = a ^ b ^ a