各位愛好編程或者希望通過學習編程進入IT行業的同學大家好,很高興能在這裏遇見你,接下來我帶你一同領略編程的魅力,以最快、最簡單、最有效的方法幫助你學習Java編程。不管你之前是零基礎還是負基礎,都能通過我的接下來的一系列文章逐步深入。
首先我們關注一下我們的基礎語法內容:
- 標識符
- 關鍵字
- Java 基本數據類型
- 運算符
- 表達式和語句
- 分支
- 循環
- 方法
- 變量的作用域
- 遞歸調用
變量:
Java 語言中,對各種變量、方法和類等要素命名時使用的字符序列稱爲標識符。
Java 標識符有如下命名規則:
- 標識符由字母、下劃線“_” 、美元符“$”或數字組成。
- 標識符應以字母、下劃線 、美元符開頭。
- Java 標識符大小寫敏感,長度無限制。
- 約定俗成:Java 標識符選取因注意“見名知意”且不能與 Java 語言的關鍵字重名。
舉例說明:
|
關鍵字
- Java 中一些賦以特定的含義,用做專門用途的字符串稱爲關鍵字(keyword)。
- 所有Java關鍵字都是小寫英文字符串。
- goto 和 const 雖然從未使用,但也作被爲 Java 關鍵字保留。
Java常量
通俗簡單來說呢:就是Java中保持不變的量
- Java 的常量值用字符串表示,區分不同的數據類型。
- 如整型常量 123
- 實型常量 3.14 字符常量 ‘a’ 邏輯常量 true、false
- 字符串常量 “helloworld”
- null
注意:
- 區分字符常量和字符串常量
- 區分 null 和 “”
- 常量的定義: public static final double PI = 3.14; Math.PI 端口、錯誤碼
Java變量
給你打個比方吧,把計算機的內存好比是一個酒店,每一個變量就好比這個酒店的每一個房間,每個房間都有門牌號,就好比變量的變量名稱;每個房間裏面的客人就像變量裏面存儲的值。
- Java變量是程序中最基本的存儲單元,其要素包括變量名,變量類型和作用域。
- Java程序中每一個變量都屬於特定的數據類型,在使用前必須對其聲明,
- 聲明格式爲: type varName [=value][{,varName[=value]}] 例如:
-
public class TestVar{ public static void main(String[] args){ int i = 100; double d1, d2, d3 = 0.123; String name = "Jack"; } }
- 從本質上講,變量其實是內存中的一小塊區域,使用變量名來訪問這塊區域,因此,每一個變量使用前必須要先申請(聲明),然後必須進行賦值(填充內容),才能使用
程序執行過程
- 聊聊程序在執行過程中的步驟,
- 首先程序是從硬盤上加載到內存裏面
- 這裏的內存指的是運行時內存(RAM)
JVM內存結構
1.程序計數器 PC Register
每個線程都有一個程序計算器,就是一個指針,指向方法區中的方法字節碼(下一個將要執行的指令代碼),由執行引擎讀取下一條指令,是一個非常小的內存空間,幾乎可以忽略不記。
2.本地方法棧 Native Method Stack
Native Method Stack中登記native方法,在Execution Engine執行時加載native libraies
本地方法棧與虛擬機棧基本類似,區別在於虛擬機棧爲虛擬機執行的java方法服務,而本地方法棧則是爲Native方法服務
3.方法區 Method Area
用於存儲虛擬機加載的:靜態變量+常量+類信息+運行時常量池 (類信息:類的版本、字段、方法、接口、構造函數等描述信息 )
默認最小值爲16MB,最大值爲64MB,可以通過-XX:PermSize
和 -XX:MaxPermSize
參數限制方法區的大小
4.棧 JVM Stack
編譯器可知的各種基本數據類型(boolean
、byte
、char
、short
、int
、float
、long
、double
)、對象引用(引用指針,並非對象本身)
棧是java 方法執行的內存模型:
每個方法被執行的時候 都會創建一個“棧幀”用於存儲局部變量表(包括參數)、操作棧、方法出口等信息。
每個方法被調用到執行完的過程,就對應着一個棧幀在虛擬機棧中從入棧到出棧的過程。
(局部變量表:存放了編譯器可知的各種基本數據類型(boolean
、byte
、char
、short
、int
、float
、long
、double
)、對象引用(引用指針,並非對象本身),
其中64位長度的long和double類型的數據會佔用2個局部變量的空間,其餘數據類型只佔1個。
局部變量表所需的內存空間在編譯期間完成分配,當進入一個方法時,這個方法需要在棧幀中分配多大的局部變量是完全確定的,在運行期間棧幀不會改變局部變量表的大小空間)
棧的生命期是跟隨線程的生命期,線程創建時創建,線程結束棧內存也就釋放,是線程私有的。
5.堆 Java Heap
所有的對象實例以及數組都要在堆上分配,此內存區域的唯一目的就是存放對象實例
堆是Java 虛擬機所管理的內存中最大的一塊。Java 堆是被所有線程共享的一塊內存區域,在虛擬機啓動時創建
堆是理解Java GC機制最重要的區域,沒有之一
結構:新生代(Eden區+2個Survivor區) 老年代 永久代(HotSpot有)
6.直接內存 Direct Memor
直接內存並不是JVM管理的內存,可以這樣理解,直接內存,就是JVM以外的機器內存,比如,你有4G的內存,JVM佔用了1G,則其餘的3G就是直接內存
JDK中有一種基於通道(Channel)和緩衝區(Buffer)的內存分配方式,將由C語言實現的native函數庫分配在直接內存中,用存儲在JVM堆中的DirectByteBuffer來引用
由於直接內存收到本機器內存的限制,所以也可能出現OutOfMemoryError的異常。
Java變量的分類
按被聲明的位置劃分:
- 局部變量:方法或語句塊內部定義的變量
- 成員變量:方法外部、類的內部定義的變量
注意:類外面(與類對應的大括號外面)不能有變量的聲明
按所屬的數據類型劃分:
- 基本數據類型變量
- 引用數據類型變量
局部變量,成員變量舉例:
public class TestVar{
public static String company = "NBA";
public static void main(String[] args){
String name = "curry";
System.out.println("company是成員變量:" + company);
System.out.println("name是局部變量:" + name);
}
}
變量需要先複製在運算
public void method() {
int i;
int j = i+5 ; // 編譯出錯,變量i還未被初始化
double d = 3.14;
}
變量按照類型來劃分
Java基本數據類型:
Java中定義了4類8種基本數據類型。
- 邏輯型-boolean
- 字符型- char (2) a~z A~Z 0~9 不是字符串 單引號’’
- 數值型
- 整數型- byte(1), short(2), int(4), long(8) 默認:int long l = 23L;
- 浮點數型- float(4), double(8) 默認:double float f = 3.14f;
編碼問題 Unicode 全球統一編碼 1字節8位 255 -128~127
編碼問題 byte 和 bit 區別
- bit 一個比特就是一個二進制數的最小單元,就像我們說我們能夠擁有的最小金額的錢就是一分一樣,只不過比特是在二進制數中罷了。 一個比特只能擁有一個值,不是0就是1,所以如果我給你一個值0,你可以說它就是一個比特,如果我給你兩個(00),你就可以說它們是兩個比特了。
- byte 1個byte就是一個字節,一個字節=8個bit
- 那麼1個byte = 8個bit
- 二進制的首位:1表示負數,0表示正數
- 一個字節二進制就是:10000000 到 01111111 的區間
- 二進制10000000 == -128(十進制) & 二進制01111111 == 127(十進制)
- 因此:byte的取值範圍就是 -128 到 127
代碼練習:
public class TestByte{
public static void main(String[] args){
//byte number = 127;
byte number = -128;
System.out.println(number);
}
}
邏輯型Boolean
- boolean 類型適於邏輯運算,一般用於程序流程控制 。
- boolean 類型數據只允許取值 true 或 false 用法舉例:
boolean flag;
flag = true;
if(flag) {
//do something
}
字符型char
- char 型數據用來表示通常意義上的“字符”
- char代表的是utf16編碼單元
- 字符常量爲用單引號括起來的單個字符,
- 例如: char eChar = 'a'; char cChar ='中';
注意char類型的值需要的是:引文的單引號 'A' ,而不是雙引號
char類型的練習:用兩種方法輸出“中” 的ASCII
//練習:用兩種方法輸出“中” 的ASCII
public class Test{
public static void main(String args[]){
char temp1 = '4';
char temp2 = '中';
char temp3 = 's';
System.out.println(temp2+0);
System.out.println(temp1+0);
}
}
整數類型
- Java 各整數類型有固定的表數範圍和字段長度,其不受具體操作系統的影響,以保證Java程序的可移植性。
- Java語言的整型常量默認爲int型,聲明long型常量可以後加‘ l ’或‘ L ’ ,
- 如:int i1 = 600; //正確 long l1 = 8888888888L; //必須加l否則會出錯
|
浮點類型
- 與整數類型類似,Java浮點類型有固定的表數範圍和字段長度,不受平臺影響。
- Java 浮點類型常量有兩種表示形式
- 十進制數形式,例如: 3.14 314.0 .314
- Java 浮點型常量默認爲 double 型,如要聲明一個常量爲 float 型,則需在數字後面加 f 或 F ,
- 如: double d = 12345.6; //正確 float f = 12.3f; //必須加f否則會出錯
- 下面列出 Java 的各種浮點類型
類 型 |
佔用存儲空間 |
表數範圍 |
float |
4字節 |
-3.403E38~3.403E38 |
double |
8字節 |
-1.798E308~1.798E308 |
Java類型轉換
- Java中可以從任意基本類型轉型到另外的基本類型
- 例外---> boolean 類型不可以轉換爲其他的數據類型。
- 轉換分爲默認轉換和強制轉換 整形,字符型,浮點型的數據在混合運算中相互轉換,轉換時遵循以下原則:
- 容量小的類型默認轉換爲容量大的數據類型;數據類型按容量大小排序爲:
- byte,short,char->int->long->float->double
- byte,short,char之間不會互相轉換,他們三者在計算時首先回轉換爲int類型
- 容量大的數據類型轉換爲容量小的數據類型時,要加上強制轉換符,但可能造成精度降低或溢出;使用時要格外注意。
- 有多種類型的數據混合運算時,系統首先自動的將所有數據轉換成容量最大的那一種數據類型,然後再進行計算。(看下頁)
- 實數常量(如:1.2)默認爲 double。整數常量(如:123)默認爲 int 。
多種類型的數據混合運算
有多種類型的數據混合運算時,系統首先自動的將其中容量小的數據轉換成容量最大的那一種數據類型,然後再進行計算。
- 如果其中一個運算對象是double類型的 另一個也會被轉換成double類型。
- 否則,如果其中一個運算對象是float類型的, 另一個也會被轉換成float類型的。
- 否則,如果其中一個運算對象是long類型的, 另一個也會被轉換成long類型的。
- 否則,如果其中一個運算對象是int類型的, 另一個也會被轉換成int類型的。
- 否則,如果其中一個運算對象是short類型的, 另一個也會被轉換成short類型的。
總而言之一句話:如果運算中出現了更大的類型,則小類型會轉換爲大類型計算。
變量賦值運算的問題
- 小數默認都是double類型例如:0.1
- 整數默認的類型是int類型;
- float number = 0.1; 錯誤
- float number = 0.1f;正確;
- 當賦值的時候,不能超過類型的最大值 int number = 1; 正確
- int number = 8888888888;錯誤,超過了int的最大值
- 如何接收大的數據 long number = 8888888888L;
- 如果小範圍的類型和大範圍類型計算之後會變爲大範圍類型,例如:
- ‘a’+0 這裏輸出的是 97 , why?
- float f4 = f1+f2*0.1; 錯誤 float f4 = (float)(f1+f2*0.1); 正確
糾錯練習
public void method(){
int i=1,j;
float f1=0.1; float f2=123;
long l1 = 12345678,l2=8888888888;
double d1 = 2e20,d2=124;
byte b1 = 1,b2 = 2,b3 = 129;
j = j+10;
i = i/10;
i = i*0.1;
char c1='a',c2=125;
byte b = b1-b2;
char c = c1+c2-1;
float f3 = f1+f2;
float f4 = f1+f2*0.1;
double d = d1*i+j;
float f = (float)(d1*5+d2);
}
運算符
Java 語言支持如下運算符:
- 算術運算符: +,-,*,/,%,++,--
- 關係運算符: >,<,>=,<=,= =,!=
- 邏輯運算符: !,& , | , ^ , &&,||
- !-邏輯非 &- 邏輯與 | - 邏輯或 ^ - 邏輯異或 &&- 短路與 || - 短路或
- &&, ||,! 邏輯運算符只能用於boolean身上
- 位運算符: &,|,^,~ , >>,<<,>>>
- 賦值運算符: =
- 擴展賦值運算符:+=,-=,*=,/=
- 字符串連接運算符:+
代碼案例:
自增自減的前後順序
public class Test {
public static void main(String arg[]) {
int i1 = 10, i2 = 20;
int i = i2++;
System.out.print("i=" + i);
System.out.println(" i2=" + i2);
i = ++i2;
System.out.print("i=" + i);
System.out.println(" i2=" + i2);
i = --i1;
System.out.print("i=" + i);
System.out.println(" i1=" + i1);
i = i1--;
System.out.print("i=" + i);
System.out.println(" i1=" + i1);
}
}
輸出:
- i=20 i2=21
- i=22 i2=22
- i=9 i1=9
- i=9 i1=8
注意: ++(--) 在前時先運算再取值。 在後時先取值再運算。
邏輯運算符
- 邏輯運算符:
- !-邏輯非 &- 邏輯與 | - 邏輯或 ^ - 邏輯異或
- &&- 短路與 || - 短路或 &&, ||,! 邏輯運算符只能用於boolean身上。
a |
b |
!a |
a&b |
a|b |
a^b |
a&&b |
a||b |
true |
true |
false |
true |
true |
false |
true |
true |
true |
false |
false |
false |
true |
true |
false |
true |
false |
true |
true |
false |
true |
true |
false |
true |
false |
false |
true |
false |
false |
false |
false |
false |
代碼案例:
public class Test{
public static void main(String args[]){
boolean a,b,c;
a = true; b = false;
c = a & b; System.out.println(c);
c = a | b; System.out.println(c);
c = a ^ b; System.out.println(c);
c = !a; System.out.println(c);
c = a && b;System.out.println(c);
c = a || b; System.out.println(c);
}
}
短路與具有短路作用,代碼案例如下
public class Test{
public static void main(String args[]) {
int i=1,j=2;
boolean flag1 = (i>3)&&((i+j)>5);
//第二個操作數將不再計算
boolean flag2 = (i<2)||((i+j)<6);
//第二個操作數將不再計算
}
}
賦值運算符與擴展賦值運算符
- 賦值運算符 (=)
- 當“=”兩側數據類型不一致時,可以適用默認類型轉換或使用強制類型轉換原則進行處理
- long l = 100; int i = (int)l;
- 注意:可以將整型常量直接賦值給byte, short, char等類型變量,而不需要進行強制類型轉換,只要不超出其表數範圍
- byte b = 12; char c = 100;
- X byte bb = 256; X short s = -32769;
- 當“=”兩側數據類型不一致時,可以適用默認類型轉換或使用強制類型轉換原則進行處理
- 擴展賦值運算符
運算符 |
用法舉例 |
等效的表達式 |
+= |
a += b |
a = a+b |
-= |
a -= b |
a = a-b |
*= |
a *= b |
a = a*b |
/= |
a /= b |
a = a/b |
%= |
a %= b |
a = a%b |
字符串連接符
- “+” 除用於算術加法運算外,還可用於對字符串進行連接操作
- int id = 800 + 90;
- String s = "hello" + "world";
- “+”運算符兩側的操作數中只要有一個是字符串(String)類型,系統會自動將另一個操作數轉換爲字符串然後再進行連接。
- int c = 12;
- System.out.println("c=" + c);
表達式
- 表達式是符合一定語法規則的運算符和操作數的序列
- a
- 5.0 + a
- (a-b)*c-4
- i<30 && i%10!=0
- 表達式的類型和值
- 對表達式中操作數進行運算得到的結果 稱爲表達式的值。
- 表達式值的數據類型即爲表達式的類型 。
- 表達式的運算順序
- 應按照運算符的優先級從高到低的順序進行。
- 優先級相同的運算符按照事先約定的結合方向進行。
R to L |
. ( ) { } ; ,++ -- ~ ! (data type) |
L to R |
* / % |
L to R |
+ - |
L to R |
<< >> >>> |
L to R |
< > <= >= instanceof |
L to R |
== != |
L to R |
& |
L to R |
^ |
L to R |
| |
L to R |
&& |
L to R |
|| |
R to L |
? : |
R to L |
= *= /= %= += -= <<= >>= >>>= &= ^= |= |
以上表中,從上到小,從做到右,優先級是:由高到低。
代碼練習:
- char c = (char)(Math.random()*26+’a’);
- Math.random()返回一個double值
- 所以26被轉成double進行乘法運算,乘積是個double
- 爲了完成加法,a必須被轉成double
- 最後獲得的double再轉成char
- 如果從29.7轉成char,是30還是29?
- Math.random()輸出0-1之間的數。[0,1)
Scanner掃描器:
Scanner類:掃描器,是JDK中一個常用的工具類,來自於java.util包中,主要用來接收用戶輸入的信息。
代碼案例:
import java.util.Scanner;
public class TestScanner{
public static void main(String[] args){
System.out.print("您好,請輸入您的名字:");
Scanner sc = new Scanner(System.in);
String name = sc.next();
System.out.print(name+",歡迎你進入java世界");
}
}
代碼練習:
做練習:
- 電腦輸入自己的:名字,性別,出生年,身高,體重。
- 返回電腦自動返回:
- 庫裏
- 男
- 1988年出生,今年27
- 身高:191.1cm
- 體重:83.9kg
- 男性:身高(釐米)-105= 標準體重(千克),
- 女性:身高(釐米)-100= 標準體重(千克)
未完待續,請關注下一篇文章~