# Java常量與變量
[TOC]
## 導學
要想要編寫規范、可讀性高的 Java 程序,就必須對 Java 基本語法有所了解。基本語法是所有編程語言都必須掌握的基礎知識,也是整個程序代碼不可缺少的重要部分。
一個 Java 程序通常由數據類型、變量、運算符和流程控制語句4部分組成。其中數據類型和運算符不僅定義了語言的規范,還決定了可以執行什么樣的操作,變量是用來存儲指定類型的數據,其值在程序運行期間是可變的;與變量對應的是常量,其值是固定的。
在之前的課程中,我們提到Java的學習,其實和英語等外語的學習并沒有什么差別。那么我們今天就要來學習一下Java中特殊字符及其作用。
## 標識符
Java 中標識符是為方法、變量或者其他用戶定義項定義的名稱。**標識符用來對變量、常量、類和方法等進行命名。因此,一個良好的編程習慣要求命名標識符時,應賦予它一個有意義或有用途的名字。** 標識符可以有一個或多個字符。在 Java 語言中,標識符的構成規則如下:
* **標識符由數字(0~9)、美元符號($)、下劃線(\_)以及Unicode字符集組合構成。**
* **標識符各符號之間沒有空格。**
* **標識符第一個字符不能為數字。**
* **標識符不能為關鍵字和保留字。**
* **標識符的命名最好能反映其作用**
例如以下為合法與不合法標識符:
* 合法標識符:hello、Hello、$hello2019、\_hello 等。
* 不合法標識符:123c、2com、for、if。
>[danger] 注意:Java 區分大小寫,因此 hello 和 Hello 是兩個不同的標識符。
> 注意:Java中的標識符也包括關鍵字
## 關鍵字
Java 的關鍵字對 Java 編譯器有特殊的意義,它們用來表示一種數據類型,或者表示程序的結構等。保留字是為 Java 預留的關鍵字,它們雖然現在沒有作為關鍵字,但在以后的升級版本中有可能作為關鍵字。
Java 語言目前定義了 51 個關鍵字,這些關鍵字不能作為變量名、類名和方法名來使用。
>[info] 數據類型:boolean、int、long、short、byte、float、double、char、class、interface
>[warning] 流程控制:if、else、do、while、for、switch、case、default、break、continue、return、try、catch、finally
>[info] 修飾符:public、protected、private、final、void、static、strict、abstract、transient、synchronized、volatile、native
>[warning] 動作:package、import、throw、throws、extends、implments、this、super、instanceof、new
>[info] 保留字:true、false、null、goto、const
**對于關鍵字的記憶,大家沒有必要死記硬背,而是靠大家在日常的學習中不斷的積累**
## 注釋
注釋是對程序語言的說明,有助于開發者和用戶之間的交流,方便理解程序。**注釋不是編程語句**,因此編譯器忽略。
Java 支持以下三種注釋方式:
* 單行注釋:以雙斜杠“//”標識,只能注釋一行內容,用在注釋信息內容少的地方。
~~~
public class Test {
public static void main(String[] args) {
// 這是單行注釋
System.out.println("單行注釋");
}
}
~~~
* 多行注釋:包含在“/\*”和“\*/”之間,能注釋很多行的內容。
~~~
public class Test {
public static void main(String[] args) {
/*
* 這是第一行注釋
* 這是第二行注釋
*/
System.out.println("多行注釋");
}
}
~~~
* 文檔注釋:包含在“/\*\*”和“\*/”之間,也能注釋多行內容,一般用在類、方法和變量上面,用來描述其作用。
~~~
/**
* 這里是文檔注釋
* @auther dodoke
*/
public class Test {
public static void main(String[] args) {
System.out.println("文檔注釋");
}
}
~~~
## 變量
在之前的學習中,我們學習過JavaScript的變量。但是要**注意區分Java中變量和js中變量的區別**。
### 什么是變量
在程序的開發過程中,我們經常要對一些數據進行處理,比如一些數學運算,我們要對一些中間的結果進行存儲,就需要設置一個新的數來存儲該結果。比如例如一個簡單的方程,x,y 都是變量,他們的值都是1,求x+y,那么我們就需要一個新的代表來表示最終的結果,比如z=x+y。z就是我們新設置的變量。
由此可知,變量就是初中數學的代數的概念,用來代表一個數據。
>[warning]變量的三個元素:變量類型 變量名 = 變量值

### 變量的命名規則
需要注意的是,剛剛我們提到標識符可以用來對變量進行命名,所以變量名也是一個標識符。
所以變量名需要進行滿足如下的命名規則:
1. 滿足標識符的命名規則
2. 符合駝峰法命名規范
3. 盡量簡單,做到見名如意
4. 變量名的長度沒有限制,但盡量做到第三條
### 變量的聲明與賦值
在 Java 中,變量分為兩種:基本類型變量和引用類型變量。本節課,我們以討論基本類型的變量為主。變量必須**先聲明后使用**,在聲明變量的時候,可以給它一個初始值。例如:
~~~
int x = 1;
~~~
上述語句聲明了一個整型 int 類型的變量,名稱為 x,初始值為 1。
變量的一個重要特點是可以重新賦值。例如:對變量 x,先賦值100,在賦值200:
~~~
public class Test {
public static void main(String[] args) {
int x = 100; // 定義int類型變量x,并賦予初始值100(變量的初始化)
System.out.println(x); // 打印該變量的值,觀察是否為100
x = 200; // 重新賦值為200
System.out.println(x); // 打印該變量的值,觀察是否為200
}
}
~~~
注意到第一次定義變量 x 的時候,需要指定變量類型 int,因此使用語句 int x = 100;。而第二次重新賦值的時候,變量 x 已經存在了,不能再重復定義,因此不能指定變量類型 int,必須使用語句 x = 200;。
## 數據類型

基本數據類型是CPU可以直接進行運算的類型。Java 定義了以下幾種基本數據類型:
* 整數類型:byte、short、int、long
* 浮點數類型:float、double
* 字符類型:char
* 布爾類型:boolean
### 整型
對于整型類型,Java 只定義了帶符號的整型,各種整型能表示的最大范圍如下:
* byte:-128~127
* short:-32768~32767
* int:-2147483648~2147483647
* long:-9223372036854775808~9223372036854775807
>[info] Java 默認的整數類型是 int,例如,128,11 都是 int 型數值。如果要說明一個 long 類型數值,就需要在其后追加字母 l 或者 L,一般使用 F,如 11L 和 128L 都是 long 類型的數值。
### 浮點數
浮點類型是帶有小數部分的數據類型,也叫實型。浮點型數據包括單精度浮點型(float)和雙精度浮點型(double),代表有小數精度要求的數字。
>[info] Java 默認的浮點型為 double,例如,11.11 和 1.2345 都是 double 型數值。如果要說明一個 float 類型數值,就需要在其后追加字母 f 或 F,如 11.11f 和 1.2345F 都是 float 類型的常數。
### 布爾型
布爾類型(boolean)用于對兩個數值通過邏輯運算,判斷結果是“真”還是“假”。Java 中用保留字 true 和 false 來代表邏輯運算中的“真”和“假”。因此,一個 boolean 類型的變量或表達式只能是取 true 和 false 這兩個值中的一個。
### 字符型
Java 語言中的字符類型(char)使用兩個字節的 Unicode 編碼表示,它支持世界上所有語言,可以使用**單引號字符**或者**整數**對 char 型賦值。
一般計算機語言使用 ASCII 編碼,用一個字節表示一個字符。ASCII 碼是 Unicode 碼的一個子集,用 Unicode 表示 ASCII 碼時,其高字節為 0,它是其前 255 個字符。
Unicode 字符通常用十六進制表示。例如“\\u0000”~“\\u00ff”表示 ASCII 碼集。“\\u”表示轉義字符,它用來表示其后 4 個十六進制數字是 Unicode 碼。
~~~
public static void main(String[] args) {
char a = 'a';
char b = 98;
char c = '\u0063';
}
~~~
### 基本數據類型變量在內存中的存儲
變量按照數據類型可以分為基本數據類型和引用數據類型,引用數據類型的包括數組和類等,類定義的變量又稱之為對象。
如果按照作用范圍來分,則可以分為類級,對象實例級,方法級,塊級。本節課程重點介紹方法級的變量如何在內存中進行存儲,方法級變量又稱之為局部變量。
通常我們可以把內存分為三個區域:

當前我們在主方法中存儲的局部變量是存儲在內存的棧區的。
~~~
int n = 100;
//該語句執行的時候,會先在棧區開辟int類型大小的空間(占用4字節,32位二進制的空間)
//在開辟完成后,通過賦值等于號,將100存儲到開辟的空間中去
//所以此處可以將n,看做100所在的內存空間的別名
~~~
### 補充:Unicode編碼
在之前的字符型變量的學習中,我們了解到了ASCII碼,他也稱之為美國標準信息交換代碼,用于規定拉丁字母的標準計算機編碼,主要用于顯示現代英語和其它西歐語言,但是對于中文和其他一些語言是不支持的。為了支持其他語言,所以出現了Unicode編碼。
Unicode編碼又稱為統一碼,萬國碼。其目標是支持世界上所有的字符集。
## 字符串的簡單介紹
字符串比較特殊,**它不屬于基本數據類型,它是類!** 但是字符串又比較特殊,它有一些和基本數據類型比較類似的地方,比如它變量的定義形式。
~~~
String str = "Hello,World!";
~~~
字符串是由雙引號引起來的0個或多個字符,**注意:字符串允許是空字符串!**
## 類型轉換
### 類型裝換
類型轉換分為自動類型轉換和強制類型轉換。
* **自動類型轉換**
把某種基本數據類型的值,直接賦值給其他基本數據類型的值
> 如果把范圍小的數據,賦值給范圍大的數據時,不會出現精度的缺失;反之,則可能會出現精度的缺失。

~~~Java
//示例
class Client1 {
public static void main(String[] args) {
int i = 100;
double di = i;
//int a = di;
System.out.println(di);
}
}
~~~
注意:
>[danger] 1.上方代碼左邊轉為右邊的數據類型是沒有問題的;
> 2.當把任何基本數據和字符串,進行連接運算的時候,基本數據類型將自動轉換為字符串類型。
* **強制數據類型轉換**
如果需要把上方代碼中的右邊,轉換為左邊時,則成為強制類型轉換。
語法:`(targetType)value`
強制類型轉換時,需加上()運算符。
**強制類型轉換也許會出現精度的缺失或溢出的情況。**
~~~
示例:
int i = 150;
byte b = (byte)i;
System.out.println(b);
int i2 = 100;
byte b2 = (byte)i2;
System.out.println(b2);
String s = "56";
int si = Integer.parseInt(s);
System.out.println(si);
~~~
**如果希望把String類型的數據,強制轉為基本數據類型,可以使用基本數據對應的包裝類實現。**
### 表達式的自動提升
當一個表達式中包含多個基本數據類型的值時,整個算術表達式的數據類型將發生自動提升。
提升規則:
所有的byte/short/char類型將被提升到int;
整個算術表達式的數據類型,將被提升到與表達中最高等級操作數相同的類型。
~~~
示例:
char t1 = 'a';
short t2 = 100;
int t3 = 45;
double t4 = 10.5;
System.out.println(t1 + t2 + t3 + t4);
~~~
**如果表達式包含字符串,應當把+號,當做字符串連接運算符,而不是加法運算符。**
## 常量
常量是指在程序的整個運行過程中值保持不變的量。在這里要注意常量和常量值是不同的概念,常量值是常量的具體和直觀的表現形式,常量是形式化的表現。
* 常量值:常量值又稱為字面常量,它是通過數據直接表示的。
* 整型常量值
* 十進制數:如 11、45等;
* 二進制數:二進制常數的表示以 0b 開頭,如 0b00001010 表示十進制 10。
* 八進制數:八進制常數的表示以 0 開頭,如 0125 表示十進制數 85。
* 十六進制數:十六進制常數的表示以 0x 或者 0X 開頭,如0x100 表示十進制數 256。
* 浮點型常量值
* 十進制數:由數字和小數點組成,且必須有小數點,如 12.34、98.0。
* 科學計數法:如 1.75e5、32E3,其中 e 或者 E 之前必須有數字,且 e 或 E 之后的數字必須為整數。
* 布爾型常量值:布爾型常量只有兩個值,即 false(假)和 true(真)。
* 字符型常量
* 單引號字符:使用單引號引起來的一個字符或者一串轉義字符,如 'a','\\u62' 都表示字符a。
* 數值:使用數值來表示,如 65 表示字符 A,97 表示字符 a。
* 常量:常量不同于常量值,它可以在程序中用標識符來代替常量值使用,因此使用前必須先定義。
* 使用 final 關鍵字來定義常量。
* 聲明常量的同時要賦予一個初始值。
* 常量一旦初始化就不可以被修改。
* 為了與變量區別,常量聲明一般都用大寫字符。
~~~
final double PI = 3.14159265;
~~~
## 練習
一、選擇
1. 下列屬于合法的 Java 標識符是?(多選)
~~~
A. $value B. Void C. class D. 1abc E. my value F.void_class
~~~
2. 下列哪一個選項不是Java的關鍵字?
~~~
A. class B. package C. Void D. static
~~~
3. 下列可以表示數值型數據的數據類型是?(多選)
~~~
A. byte B. float C. boolean D. long
~~~
4. 關于數據類型的說法錯誤的是?
~~~
A. 數據類型分為基本數據類型和引用數據類型
B. 數組屬于基本數據類型
C. 類屬于引用數據類型
D. int和double屬于基本數據類型
~~~
5. 下列關于賦值運算符的說法正確的是?(多選)
~~~
A. 使用“=”給變量進行賦值
B. 使用“==”給變量進行賦值
C. "="叫作賦值運算符,將運算符右邊的值賦給左邊的變量
D. "="叫作賦值運算符,將運算符左邊的值賦給右邊的變量
~~~
6. 以下對double類型字面值的表示錯誤的是?
~~~
A. 1.23 B. 1.23d C. 1.23D D.1.23f
~~~
7. 以下語句哪個是錯誤的?
~~~
A. double d=12.3d; B. double d=12.3D; C. float f=1.23f; D.float f=1.23;
~~~
8. 下面代碼運行后的結果為?

~~~
A. A B. 65 C. A 65 D.A A
~~~
9. 以下字符型字面值中,不合法的是?
~~~
A. '@' B. '&' C. "M" D.'課'
~~~
10. 以下哪兩個是合法的字符串字面值?(多選)
~~~
A. "" B. 'ab' C. 'a' D."\u0067"
~~~
11. 以下哪兩條語句是正確的?(多選)
~~~
A. char ch=65539; B. int n=5.6f; C. double d=1.2f; D. double d=1.23;float f=(float)d;
~~~
二、編程
1. 分別定義float、double、int類型的數據,并打印輸出。
~~~
public class FloatDemo {
public static void main(String[] args) {
// 定義一個float類型的變量f1,值為98.4
//定義一個float類型的變量f2,將f1的值賦值給f2
//定義一個整型變量n,值為55
//定義一個double類型的變量d1,值為555.3
//將n的值賦值給d1
}
}
~~~
2. 定義字符型變量,賦值后輸出。
~~~
public class CharTest {
public static void main(String[] args) {
// 定義字符變量c,并賦值為'S'
//輸出c的值
//定義字符變量c1,并賦值為78
//輸出c1的值
}
}
~~~
3. 定義布爾類型和字符串類型的變量,為它們賦值,并打印輸出。
~~~
public class StringDemo {
public static void main(String[] args) {
// 定義一個布爾類型的變量flag,賦值為true,并輸出
//定義一個字符串類型的變量str,值為"hello world",并輸出
//定義一個字符串類型的變量str1,值為空串
//將str的值賦值給str1,并輸出
}
}
~~~
4. 定義各種數據類型的變量,為它們賦值,并打印輸出。
~~~
public class TypeExchange {
public static void main(String[] args) {
// 定義一個整型變量n,值為98
//定義一個char類型的變量ch,將變量n賦值給ch,然后輸出ch的值
//定義一個長整型變量var,值為190000000,并輸出
//定義一個double類型的變量d,將變量var的值賦值給d
}
}
~~~
5. 定義各種數據類型的變量,按要求為它們賦值,并打印輸出。
~~~
public class TypeExchange {
public static void main(String[] args) {
// 將一個整型字面值67832賦值給char類型變量c
//并將c的值輸出
//定義一個整型變量n,值為65
//定義一個字符型變量c1,賦值為n,并輸出c1的值
//定義一個長整型變量l,值為987654321
//定義一個整型變量i,賦值為l,并輸出i的值
//定義一個float類型變量f,將變量l的值賦值給f,并輸出f的值
//將float的值f,重新賦值給變量l,并輸出l的值
}
}
~~~