上次談到了Java的基本資料類型,今天接着聊Java的變量、運算符。
一、變量
1、變量的分類
變量分為成員變量、局部變量和常量,其中成員變量又分為執行個體變量、類變量。

2、變量的定義
文法:變量類型(可以是基本類型,也可以是其他) 變量名 = 變量值 英文;結尾。
2.1 可以單次聲明一個變量,也可以單次聲明多個變量。
2.2 不能以數字、運算符、特殊字元(下劃線、美元符号$除外)開頭。
2.3 下劃線 _ 可以作為開頭,但是不建議這樣命名。
2.4 可以使用中文命名,但是不建議這樣做。
2.5 不能使用現有Java關鍵字和保留字命名。
2.6 建議使用駝峰命名法。
類名的首字母大寫;變量名、方法名首字母小寫;包名全部小寫;特殊含義的縮略詞全部大寫;常量名全部大寫;多個單詞可以使用下劃線分割。做到見名知意,不要使用拼音字母縮寫、拼音全拼、英文拼音混合的命名格式,不知道如何翻譯請查字典或線上翻譯單詞。變量名長一點無所謂,命名合理、規範,見名知意就可以。
3、變量的使用
執行個體變量的使用,需要使用new關鍵字建立對象,再通過對象引用。靜态變量可以直接使用。在使用變量前,請先初始化指派,不能聲明不指派直接使用。
package javalearningday02;
/**
* 變量的使用
* @author 小川94
* @date 2018年1月21日
*/
public class UseVariable {
// 成員變量,也可以稱為全局變量,可在本類或者其他類中使用
private int age = 18;
// 聲明一個靜态常量,成員變量的一種,也是一個類變量
private static final String GENDER = "BOY";
// 常量,由關鍵字final定義
private final String NAME = "小川94";
public static void main(String[] args) {
// 在main方法中定義的局部變量
int anotherAge = 20;
// 變量的定義
int a; // 單個變量定義
int b = 2; // 單個變量定義并初始化
int c,d; // 單次定義多個變量
int _num = 1; // 可以是下劃線開頭,但是不建議
int num_ = 2; // 可以下劃線結尾
int $num; // 也可以美元符号開頭
int num2; // 可以是數字結尾
//int +num; // 錯誤寫法,不能用運算符開頭
//int .num; // 錯誤寫法,不能用.号開頭
//int 2num; // 錯誤寫法,不能以數字開頭
//int *num; // 錯誤寫法,不能以*開頭,其他特殊符号也是不可以的
int 變量 = 2; // 可以使用中文,但是建議不要使用
// 不能使用關鍵字命名
//int class; // 不能使用關鍵字
//int goto; // Java保留關鍵字(保留關鍵字是指那些現有Java版本還未使用的關鍵字,但還是關鍵字)
//int const; // Java保留關鍵字
// 不能使用保留字命名
/*
int true;
int false;
int null;*/
}
public static String askName(String name){
// 局部變量隻能在該變量定義并且初始化的操作域中使用,跨域使用會報錯
// 錯誤寫法 anotherAge cannot be resolved to a variable
//System.out.println(anotherAge);
// 不能對非靜态變量進行靜态引用
// 錯誤寫法 cannot make a static reference to the non-static field age
// System.out.println(age);
// 對于全局變量的引用,如果是非靜态的,需要利用對象引用
UseVariable useVariable = new UseVariable();
System.out.println(useVariable.age);
// 類變量(靜态成員變量)可以直接使用
System.out.println("小川94的性别是"+GENDER);
return "Hello "+name;
}
}
二、運算符
知道了資料類型,知道如何聲明一個變量并初始化,下面就開始做資料運算操作。
1、指派運算符。
=(指派),要和數學中的等号區分。
2、算術運算符。
+(加法)、-(減法)、*(乘法)、/(除法)、%(取餘)。這五種是開發中比較常用的。
關于除法:
(1)如果被除數是0,運作則會報算術異常,在做除法時需要判斷被除數是否為0。
(2)如果是兩個整數做除法,可能會丢失計算精度,選擇合适的資料類型尤為重要。
關于取餘:
(1)負數對整數的餘數是負數和0。
(2)正數的餘數是有周期性變化的。
(3)餘數是有範圍的數,可以控制資料範圍。
3、數值類型之間的轉換
數值之間的轉換可以分為自動轉換、強制轉換兩種形式。
3.1 自動轉換
如果兩個數中有一個為double類型,另一個數會被轉為double類型,然後再進行運算。
如果兩個數中有一個為float類型,另一個數會被轉為float類型,然後再進行運算。
如果兩個數中有一個為long類型,另一個數會被轉為long類型,然後再進行運算。
如果沒有上述的三種的類型,兩個數都會被轉為int進行運算。
小範圍的資料類型可以自動轉換到大範圍資料類型,大範圍的數可以涵蓋小範圍的數,小範圍内的數可以映射到大範圍内的數。
3.2 強制類型轉換
從大範圍的數向小範圍的數轉換,稱之為強制轉換,用法是在目标資料前使用括号,将想要轉換的類型輸入括号即可。
關于強制轉換,有幾點需要注意:
(1)範圍内的數,轉換是沒有損失的。
(2)double轉換為float,會出現精度損失。
(3)浮點數轉換為整數,隻會保留原數的整數位,不會保留小數位,也不會進行四舍五入操作。
(4)範圍外的數,會有溢出的風險。
4、結合指派和運算符
有時候為了省事,會把算術運算符和指派運算符連着一起寫。如:int n += 4; 這一句和int n = n+4;是等價的,其他的算術運算符也是如此,可以單獨寫在指派符号的前面。
5、自增、自減運算符
自增的文法是 變量++; 自減的文法是 變量--; 作用是将變量的值增加1,注意是變量,不是整體。
先加加(++變量)和後加加(變量++)在運算時有很大的不同。
(1)先加加,這裡為了友善簡寫為++n吧,是先将n的值加1,然後取n的值作為表達式(++n)整體的值。
int b = ++a;
-->第一步 a = a+1;
-->第二步 b = a;
(2)後加加,同樣為了友善簡寫為n++;是先将n的值作為表達式(n++)整體的值,然後将n的值加1。
int b = a++;
-->第一步 b = a;
-->第二步 a = a+1;
/**
* 後加加,先将變量值賦給整體表達式,再計算n+1。後減減同理。
*/
public static void selfAddAfter() {
int n = 5;
n = n++;
n = n++;
n = n++;
n = n++;
System.out.println("n的值是"+n); // n = 5;
}
/**
* 先加加,先将變量值加1,再将加過1後的值賦給整體表達式。先減減同理
*/
public static void selfAddBefore() {
int m = 5;
int n = ++m;
System.out.println("m的值是"+m); // m = 6;
System.out.println("n的值是"+n); // n = 6;
}
6、關系運算符
關系運算符,也可以稱為比較運算符,包括>(大于)、<(小于)、>=(大于等于)、<=(小于等于)、==(等于)、!=(不等于),比較的結果為true或false。
7、邏輯運算符
邏輯運算符,包含&&(邏輯與運算)、||(邏輯或運算)、!(邏輯非運算)
在進行邏輯運算時,會出現短路運算的情況,即前一個邏輯判斷已經可以為結果定性,後面的邏輯判斷是不會執行的。
/**
* 邏輯運算符
*/
public static void logicOperation() {
// false,并且發生了短路運算,因為3>4為false,可以直接為整個表達式定性,無需再判斷4>5表達式的值
// 與運算中,所有條件都為true時,整體表達式才為true
System.out.println(3>4 && 4>5); // 4>5下面标黃了,提示是Dead code,說明不會運作後半部分的表達式
// true,這裡也發生了短路運算,不會去判斷3>4的值
System.out.println(2>1 || 3>4);
// 或運算中,隻要有一個為true,整個表達式的值就是true
System.out.println(3>4 || 2>1);
// true,非運算中,true變false,false變true
System.out.println(!(4>5));
}
8、位運算符
與(&)、非(~)、或(|)、異或(^)、<<(帶符号左移)、>>(帶符号右移)、>>>(無符号右移),下面将詳細介紹這七種運算符。
8.1 與(&)運算
/**
* 與(&)運算
* 規則:先将要運算的數轉為二進制,當相同的位上均為1時結果為1,否則結果為0
*/
public static void andOperation() {
/**
* 98的原碼: 00000000 00000000 0000000 01100010
* 18的原碼: 00000000 00000000 0000000 00010010
* 與運算後: 00000000 00000000 0000000 00000010
* 轉換為十進制的數是2
*/
int num = 98&18;
System.out.println("(98&18)的與(&)運算結果:"+num); // num = 2
}
8.2 非(~)運算
/**
* 非(~)運算
* 規則: 正數的非運算是先取反再計算補碼,負數的非運算是先計算補碼再取反
*/
public static void nonOperation() {
byte num = ~90;
/**
* 正數非運算:原碼 -->取反(1變0,0變1,非運算)-->反碼(符号位不變,其餘1變0,0變1)--->補碼(反碼的基礎上加1)
* 90
* 原碼: 00000000 00000000 00000000 01011010
* 取反: 11111111 11111111 11111111 10100101
* 反碼: 10000000 00000000 00000000 01011010
* 補碼: 10000000 00000000 00000000 01011011
* 轉為十進制數則是-91
*/
System.out.println("90的非(~)運算結果:"+num); // num = -91
/**
* 10
* 原碼: 00000000 00000000 00000000 00001010
* 取反: 11111111 11111111 11111111 11110101
* 反碼: 10000000 00000000 00000000 00001010
* 補碼: 10000000 00000000 00000000 00001011
* 轉為十進制數是-11
*/
System.out.println("10的非(~)運算結果:"+(~10)); // -11
/**
* 負數非運算:原碼 --->反碼(符号位不變,其餘1變0,0變1)--->補碼(反碼的基礎上加1)--->取反(1變0,0變1,非運算)
* -5
* 原碼: 10000000 00000000 00000000 00000101
* 反碼: 11111111 11111111 11111111 11111010
* 補碼: 11111111 11111111 11111111 11111011
* 取反: 00000000 00000000 00000000 00000100
* 轉為十進制為 4
*/
System.out.println("(-5)的非(~)運算結果:"+(~(-5))); // 4
}
8.3 或(|)運算
/**
* 或(|)運算
* 規則:當兩邊操作數的位有一邊為1時,結果為1,否則為0。
*/
public static void orOperation() {
/**
* 23的原碼: 00000000 00000000 00000000 00010111
* 75的原碼: 00000000 00000000 00000000 01001011
* 或運算: 00000000 00000000 00000000 01011111
* 轉換為十進制數是95
*/
System.out.println("(23|75)的或(|)運算結果"+(23|75)); // 95
}
8.4 異或(^)運算
/**
* 異或(^)運算
* 規則:兩邊的對應位不同時,取1,否則取0。如果遇到負數,需要用負數的補碼進行計算
*/
public static void differentOr() {
/**
* 17的原碼: 00000000 00000000 00000000 00010001
* 29的原碼: 00000000 00000000 00000000 00011101
* 異或運算: 00000000 00000000 00000000 00001100
* 轉為十進制數是12
*/
System.out.println("(17^29)的異或(^)運算結果:"+(17^29)); //12
/**
* -17的原碼: 10000000 00000000 00000000 00010001
* -17的反碼: 11111111 11111111 11111111 11101110
* -17的補碼: 11111111 11111111 11111111 11101111
* 29的補碼: 00000000 00000000 00000000 00011101
* 運算結果: 11111111 11111111 11111111 11110010
* 對結果反碼: 10000000 00000000 00000000 00001101
* 對結果補碼: 10000000 00000000 00000000 00001110
* 結果轉為十進制數是-14
*/
System.out.println("(-17^29)的異或(^)運算結果:"+(-17^29)); //-14
}
8.5 帶符号左移(<<)運算
/**
* 帶符号左移(<<)運算
* 規則: 符号位不變,左移幾位,則在補碼(正數的補碼、反碼與原碼一樣)的後面補幾個0
* 也可以簡單了解成數學運算,左移幾位,就是原數乘以2的幾次方
*/
public static void withSymbolToLeft() {
/**
* 10的原碼: 00000000 00000000 00000000 00001010
* 左移四位: 00000000 00000000 00000000 10100000
* 轉換為十進制數是160
* 也可以了解成數學運算中的 10*(2*2*2*2) = 10*16 = 160
*/
System.out.println("(10<<4)帶符号左移(<<)運算的結果:"+(10<<4)); // 160
/**
* -9的原碼: 10000000 00000000 00000000 00001001
* -9的反碼: 11111111 11111111 11111111 11110110
* -9的補碼: 11111111 11111111 11111111 11110111
* 左移4位: 11111111 11111111 11111111 01110000
* 再反碼: 10000000 00000000 00000000 10001111
* 再補碼: 10000000 00000000 00000000 10010000
* 轉為十進制數是-144
* 也可以了解成數學運算中的 (-9)*(2*2*2*2) = (-9)*16 = -144
*/
System.out.println("(-9)<<4)帶符号左移(<<)運算的結果:"+((-9)<<4)); // -144
}
8.6 帶符号右移(>>)運算
/**
* 帶符号右移(>>)運算
* 規則: 正數右移時,右移幾位,在補碼的左邊加幾個0,右邊的被自動擠掉;
* 負數右移時,右移幾位,在補碼的左邊加幾個1,右邊的被自動擠掉
*/
public static void withSymbolToRight() {
/**
* 20的原碼: 00000000 00000000 00000000 00010100
* 右移4位: 00000000 00000000 00000000 00000001
* 轉為十進制數是1
*/
System.out.println("(20>>4)帶符号右移(>>)運算結果:"+(20>>4));
/**
* -86的原碼: 10000000 00000000 00000000 01010110
* -86的反碼: 11111111 11111111 11111111 10101001
* -86的補碼: 11111111 11111111 11111111 10101010
* 右移四位: 11111111 11111111 11111111 11111010
* 再計算反碼: 10000000 00000000 00000000 00000101
* 再計算補碼: 10000000 00000000 00000000 00000110
* 轉為十進制數是-6
*/
System.out.println("(-86)>>4帶符号右移(>>)運算結果:"+((-86)>>4)); // -6
}
8.7 無符号右移(>>>)運算
/**
* 無符号右移(>>>)運算
* 規則: 無論正數還是負數,右移幾位,則在其補碼左邊加上幾個0
*/
public static void noSymbolToRight() {
/**
* 50的原碼: 00000000 00000000 00000000 00110010
* 右移4位: 00000000 00000000 00000000 00000011
* 轉為十進制數是3
*/
System.out.println("(50>>>4)的無符号右移(>>>)運算結果:"+(50>>>4)); // 3
/**
* -28的原碼: 10000000 00000000 00000000 00011100
* -28的反碼: 11111111 11111111 11111111 11100011
* -28的補碼: 11111111 11111111 11111111 11100100
* 右移四位: 00001111 11111111 11111111 11111110
* 再轉為十進制數是 0+0+0+0+134217728+67108864+33554432+16777216
* +8388608+4194304+2097152+1048576+524288+262144+131072+65536
* +32768+16384+8192+4096+2048+1024+512+256
* +128+64+32+16+8+4+2+0 = 268435454
*/
System.out.println("(-28)>>>4的無符号右移(>>>)運算結果:"+((-28)>>>4)); // 268435454
}
9 三目運算符
文法為 條件 ? 條件為true執行 : 條件為false執行 。可以單個寫,也可以多層嵌套,但是如果條件比較複雜,建議單獨抽出來處理,便于閱讀和維護。
public static void threeHeadOperation() {
int n = 3;
int m = 10;
int maxNum = n>m ? n : m; //單個寫法
System.out.println(maxNum); // maxNum = 10
// 設定忽略num小于0的情況
int num = 4;
String str = num != 0 ? num%2 == 0 ? "是偶數" : "是奇數" : "是0";
System.out.println(str); // 是偶數
// 上面的三目運算符等價于下面的代碼
if (num != 0) {
if (num%2 == 0) {
System.out.println("num是偶數");
} else {
System.out.println("num是奇數");
}
} else {
System.out.println("num是0");
}
}
10 instanceof
public class JavaOperation {
public static void main(String[] args) {
instanceOfOperation();
}
/**
* instanceof 是用來在運作時指出對象是否是特定類的一個執行個體
*/
public static void instanceOfOperation() {
A a = new A();
String str = a instanceof A ? "a是A的執行個體" : "a不是A的執行個體";
System.out.println(str); // a是A的執行個體
String str2 = null instanceof A ? "null是A的執行個體" : "null不是A的執行個體";
System.out.println(str2); // null不是A的執行個體
}
}
class A{
}
Java入門(三)源碼已經上傳Github,位址:https://github.com/XiaoChuan94/javalearning/tree/master/javalearningday02,可以參考。
文章首發于我的個人公衆号:悅樂書。喜歡分享一路上聽過的歌,看過的電影,讀過的書,敲過的代碼,深夜的沉思。期待你的關注!
公衆号背景輸入關鍵字“Java學習電子書”,即可獲得12本Java學習相關的電子書資源,如果經濟能力允許,還請支援圖書作者的紙質正版書籍,創作不易。