JAVA基礎總結

Java 編程基礎............................................................................................................ - 3 -html

1、         前言....................................................................................................... - 3 -java

1.     JAVA 軟件工程師的崗位要求................................................................. - 3 -node

2、         Java概述:............................................................................................ - 4 -es6

1.     Java的三種技術架構.............................................................................. - 4 -web

2.     JDK、JRE、JVM三者間的關係............................................................. - 4 -正則表達式

3.     Java運行環境配置................................................................................. - 5 -sql

4.     Java與Javac命令................................................................................. - 6 -shell

5.     Java編譯過程........................................................................................ - 7 -數據庫

6.     Java內存處理機制................................................................................. - 7 -編程

7.     經常使用DOS命令....................................................................................... - 7 -

3、         Java編程風格與命名規範....................................................................... - 8 -

1.     格式規範................................................................................................ - 8 -

2.     命名規範................................................................................................ - 8 -

4、         語法基本元素......................................................................................... - 9 -

1.     關鍵字................................................................................................... - 9 -

2.     標識符................................................................................................... - 9 -

3.     數據類型、常量和變量......................................................................... - 10 -

4.     運算符和表達式.................................................................................... - 11 -

5、         流程控制.............................................................................................. - 14 -

1.     循環語句.............................................................................................. - 14 -

2.     判斷語句.............................................................................................. - 14 -

3.     跳轉語句.............................................................................................. - 14 -

4.     flag 或index標記的用法..................................................................... - 15 -

6、         數組..................................................................................................... - 16 -

1.     數組的經常使用操做................................................................................... - 16 -

2.     二維數組.............................................................................................. - 17 -

Java 面向對象.......................................................................................................... - 19 -

1、         前言..................................................................................................... - 19 -

2、         類和對象.............................................................................................. - 19 -

1.     類和對象的定義................................................................................... - 19 -

2.     類的建立和使用................................................................................... - 19 -

3.     對象的建立和使用................................................................................ - 20 -

4.     成員變量VS局部變量.......................................................................... - 20 -

5.     成員方法VS方法................................................................................. - 21 -

6.     構造方法.............................................................................................. - 22 -

7.     補充幾點.............................................................................................. - 22 -

3、         封裝、繼承和多態................................................................................ - 25 -

1.     封裝..................................................................................................... - 25 -

2.     繼承..................................................................................................... - 26 -

3.     多態..................................................................................................... - 27 -

4、         抽象類和接口....................................................................................... - 30 -

1.     抽象類(abstract).............................................................................. - 30 -

2.     接口(interface)................................................................................ - 31 -

3.     抽象類和接口的對比............................................................................ - 32 -

5、         異常..................................................................................................... - 33 -

1.     JAVA異常............................................................................................ - 33 -

2.     處理異常機制....................................................................................... - 34 -

3.     捕獲異常try / catch 和 finally.............................................................. - 34 -

4.     拋出異常 throws和throw.................................................................... - 35 -

5.     Java常見異常...................................................................................... - 35 -

6.     自定義異常.......................................................................................... - 36 -

7.     Java異常處理的原則和技巧................................................................. - 36 -

8.     補充幾點.............................................................................................. - 36 -

6、         面向對象的幾點猜測............................................................................ - 36 -

Java 高級特性.......................................................................................................... - 37 -

1、         集合框架和泛型................................................................................... - 37 -

1.     集合 框架 API..................................................................................... - 37 -

2.     Iterator 迭代器.................................................................................... - 40 -

3.     Collections包裝類............................................................................... - 41 -

4.     補充幾點.............................................................................................. - 42 -

5.     泛型..................................................................................................... - 42 -

2、         實用類................................................................................................. - 42 -

1.     枚舉..................................................................................................... - 43 -

2.     包裝類................................................................................................. - 43 -

3.     Math類................................................................................................ - 44 -

4.     String類.............................................................................................. - 44 -

5.     StringBufffer類和StringBulider類...................................................... - 45 -

6.     日期時間類.......................................................................................... - 45 -

7.     Random類........................................................................................... - 46 -

3、         輸入/輸出、序列化和反射.................................................................... - 46 -

1.     File類的操做....................................................................................... - 46 -

2.     Java的流............................................................................................. - 47 -

3.     讀寫文本文檔....................................................................................... - 47 -

4.     讀寫二進制文檔................................................................................... - 50 -

5.     重定向標準 I/O.................................................................................... - 51 -

6.     序列化與反序列化................................................................................ - 51 -

7.     反射機制.............................................................................................. - 52 -

8.     補充幾點.............................................................................................. - 52 -

4、         註解和多線程....................................................................................... - 53 -

1.     註解..................................................................................................... - 53 -

2.     多線程................................................................................................. - 54 -

5、         網絡編程.............................................................................................. - 57 -

1.     網絡基礎知識....................................................................................... - 57 -

2.     InetAddress......................................................................................... - 58 -

3.     URL類................................................................................................. - 58 -

4.     TCP編程............................................................................................. - 59 -

5.     UDP編程............................................................................................. - 63 -

6.     注意問題.............................................................................................. - 65 -

6、         XML..................................................................................................... - 65 -

1.     XML 基礎............................................................................................ - 65 -

2.     XML 註釋............................................................................................ - 65 -

3.     XML 解析............................................................................................ - 65 -

7、         GUI...................................................................................................... - 68 -

8、         正則表達式.......................................................................................... - 73 -

 

Java 編程基礎

1、      前言

1.     JAVA 軟件工程師的崗位要求

1.基礎紮實,具有良好面向對象設計能力和範化的編程風格;熟悉MVC設計模式;

2.熟悉CSS/HTML, JavaScript, XML/XSL, Ajax,Jquery等Web腳本語言技術

3.熟練掌握Oracle/MySQL等主流數據庫,瞭解數據庫內部機制和原理;

4.熟練基於J2EE的相關開源技術以及框架(Spring,SpringMVC,MyBatis,Hibernate);

5.熟練使用Tomcat、Apache,Nginx,servlet等應用和服務器配置;

6.熟練使用Junit編寫測試代碼,Maven代碼管理工具;

7.瞭解UML等建模語言、PowerDesigner等設計經常使用工具;

8.項目工做經驗

 

2、      Java概述:

1991 年Sun公司的James Gosling等人開始開發名稱爲 Oak 的語言,但願用於控制嵌入在有線電視交換盒、PDA等的微處理器;1994年將Oak語言改名爲Java

1.     Java的三種技術架構

a)      JAVAEE

Java Platform Enterprise Edition,開發企業環境下的應用程序,主要針對web開發。

a)      JAVASE

Java Platform Standard Edition,完成桌面應用程序的開發,是其它二者的基礎。

b)     JAVAME

Java Platform Micro Edition,開發電子消費產品和嵌入式設備,如手機中的程序。

2.     JDK、JRE、JVM三者間的關係

a)      JDK:Java Development Kit

JDK是整個JAVA的核心,包括了Java運行環境JRE(Java Runtime Envirnment)、一堆Java工具(Javac/Java/jdb等)和Java基礎的類庫(即Java API 包括rt.jar)。

在JDK的安裝目錄下有一個名爲jre的目錄,裏面有兩個文件夾bin和lib,在這裏能夠認爲bin裏的就是jvm,lib中則是jvm工做所須要的類庫,而jvm和 lib和起來就稱爲jre。

b)     JRE:Java Runtime Environment

Java程序的運行環境,Java運行的所需的類庫+JVM(Java虛擬機)。與JDK不一樣,JRE是Java運行環境,並非一個開發環境,因此沒有包含任何開發工具(如編譯器和調試器),只是針對於使用Java程序的用戶。

c)      JVM:Java virtual machine

Java虛擬機的縮寫,是整個Java實現跨平臺的最核心的部分,全部的Java程序會首先被編譯爲.class的類文件,這種類文件能夠在虛擬機上執行。

也就是說class並不直接與機器的操做系統相對應,而是通過虛擬機間接與操做系統交互,由虛擬機將程序解釋給本地系統執行。

只有JVM還不能成class的執行,由於在解釋class的時候JVM須要調用解釋所須要的類庫lib,而jre包含lib類庫。

配置環境變量是爲了讓Java jdk\bin目錄下的工具,能夠在任意目錄下運行,緣由是,將該工具所在目錄告訴了系統,當使用該工具時,由系統幫咱們去找指定的目錄。JAVA_HOME---
Java運行環境配置

b)     PATH環境變量

做用是指定命令搜索路徑,在shell下面執行命令時,它會到PATH變量所指定的路徑中查找看是否能找到相應的命令程序。咱們須要把 jdk安裝目錄下的bin目錄增長到現有的PATH變量中,bin目錄中包含常常要用到的可執行文件如Javac/Java/Javadoc等,設置好 PATH變量後,就能夠在任何目錄下執行Javac/Java等工具了。

c)      CLASSPATH環境變量

做用是指定類搜索路徑,要使用已經編寫好的類,前提固然是可以找到它們了,JVM就是經過CLASSPTH來尋找類的。咱們 須要把jdk安裝目錄下的lib子目錄中的dt.jar和tools.jar設置到CLASSPATH中,固然,當前目錄「.」也必須加入到該變量中。

d)     JAVA_HOME環境變量

它指向jdk的安裝目錄,Eclipse/NetBeans/Tomcat等軟件就是經過搜索JAVA_HOME變量來找到並使用安裝好的jdk

e)     永久配置方式

Java_HomeC:\Program Files\Java\jdk1.7.0_07

Path:            %Java_Home%\bin;%Java_Home%\jre\bin;

ClassPath. ; %Java_Home%\bin;%Java_Home%\lib\dt.jar;%Java_Home%\lib\tools.jar

特色:系統默認先去當前路徑下找要執行的程序,若是沒有,再去path中設置的路徑下找

f)      臨時配置方式(DOS)

set path=%path%;C:\Program Files\Java\jdk\bin         set classpath=XXX

註釋:環境變量的配置已經完成,DOS命令下輸入Java/Javac/Java –version檢測。

g)     補充幾點

若是沒有定義環境變量classpath,Java啓動JVM後,會在當前目錄下查找要運行的類文件;若是指定了classpath,那麼會在指定的目錄下查找要運行的類文件。

還會在當前目錄找嗎?兩種狀況:

  • Ø  若是classpath的值結尾處有分號,在具體路徑中沒有找到運行的類,會默認在當前目錄再找一次。
  • Ø  若是classpath的值結果出沒有分號,在具體的路徑中沒有找到運行的類,不會再當前目錄找。
  • Ø  通常不指定分號,若是沒有在指定目錄下找到要運行的類文件,就報錯,這樣能夠調試程序。

4.     Java與Javac命令

       Java是分兩部分的:一個是編譯,一個是運行。

  • Javac負責的是編譯的部分,當執行Javac時,會啓動Java的編譯器程序。對指定擴展名的.Java文件進行編譯。 生成了jvm能夠識別的字節碼文件。也就是class文件,也就是Java的運行程序。
  • Java負責運行的部分.會啓動JVM加載運行時所需的類庫,並對class文件進行執行。
  • javac MyInfo.Java
  • java MyInfo

5.     Java編譯過程

6.     Java內存處理機制

待補充~

7.     經常使用DOS命令

md

建立文件夾

cd

進入文件夾

del

刪除文件夾

copy

複製文件

rd

刪除文件夾

cd..

後退一級

cls

清屏

help

幫助

dir

列出目錄

cd\

進入根目錄

ren

重命名

 

 

 

詳見經常使用DOS命令大全及其用法

 

 


 

3、      Java編程風格與命名規範

1.     格式規範

a)      縮進嵌套的代碼

b)     斷開很長的句子

c)      使用空白

d)     不要直接使用Tab控制符

2.     命名規範

a)     JAVA源文件的命名  

JAVA源文件名必須和源文件中所定義的類的類名相同。且不能爲關鍵字

b)     Package的命名  

Package名的第一部分應是小寫ASCII字符,而且是頂級域名之一,一般是com、edu、gov、mil、net、org或由ISO標準316六、1981定義的國家惟一標誌碼。Package名的後續部分由各組織內部命名規則決定,內部命名規則指定了各組件的目錄名,所屬部門名、項目名等。   

c)     Class/Interface的命名  

Class名應是首字母大寫的名詞,    並且大寫中間單詞的首字母。命名時應該使其簡潔而又具備描述性。異常類的命名,應以Exception結尾。Interface的命名規則與Class相同。

d)     常量的命名  

常量名的字母應所有大寫,不一樣單詞之間經過下劃線鏈接,而且名字組合應該賦予含義。

e)     變量的命名

  • 普通變量 

普通變量名的首字母小寫,其它每一個單詞的首字母大寫。命名時應該使其簡短而又有特定含義,簡潔明瞭的向使用者展現其使用意圖。    

  • 約定變量  

所謂約定變量,是指那些使用後便可拋棄(throwaway)的臨時變量。一般i、j、k、m和n表明整型變量;c、d和e表明字符型變量。

f)      方法的命名  

方法名的第一個單詞應是動詞,而且首字母小寫,其它每一個單詞首字母大寫。  

g)     方法參數的命名 

選擇有意義的名稱做爲方法的參數名。可能的話,選擇和須要賦值的字段同樣的名字。 

詳見Java編程風格與命名規範-ZZ

4、      語法基本元素

1.     關鍵字

a)      定義:被JAVA語言賦予了特殊含義的單詞。

b)     特色:關鍵字中全部字母都爲小寫。

c)      注意:goto和const做爲保留字存在,目前並不使用。

2.    

 
   


標識符

a)      含義:標識符就是給類,接口,方法,變量等起名字時使用的連續字符序列。

b)     組成規則:① 英文大小寫字母A~Z和a~z ② 數字字符0~9$ 和 _

c)      注意事項:不能以數字開頭不能是Java中的關鍵字區分大小寫

不能有空格

3.     數據類型、常量和變量

a)      基本數據類型

byte、short、int、long、float、double、char、boolean

b)     引用數據類型

數組、類、接口。

分類

不一樣類型

關鍵字

字節數

取值範圍

默認值

整數型

字節型

byte

1個字節

-27~27-1(-128~127)

0

短整型

short

2個字節

-215~215-1(-32768~32767)

0

整型

Int (默認)

4個字節

-231~231-1

0

長整型

long

8個字節

-263~263-1

0

文本型

字符型

char

2個字節

0~216-1(從0~65536)

‘\u0000’

浮點型

單精度浮點型

float

4個字節

大約±3.40282347E+38F

(有效位數爲6~7位)

0.0f

雙精度浮點型

Double

(默認)

8個字節

大約±1.79769313486231570E+308

(有效位數爲15位)

0.0d

邏輯型

布爾型

boolean

1個字節

True/false

false

級別從低到高爲:(byte--> short),char (這兩個平級)--> int--> float--> long--> double

補充: 不一樣的字符所佔的字節是不一樣的。詳見輸入輸出章節之字符編碼。

0x  0

c)      數據類型轉換

不一樣的基本數據類型之間進行運算時須要進行類型轉換,除boolean類型外全部的基本數據類型都須要考慮類型轉換,其主要應用在算術運算和賦值運算時。

  • 自動類型轉換:除boolean型外,其餘數據類型系統自動從低級別到高級別轉換;
  • 強制類型轉換:把一個高級別的數賦給一個低級別的的變量。
  • Ø  溢出處理:待補充
  • 補充:同種類型之間才能夠進行強制裝換。錯誤舉例:String a = (String)2;

正確舉例:String a = integer.toString(2)或int i = integer.parseInt(s);

d)     變量

全部局部變量在使用前都得初始化。詳見類與對象部分。

e)     常量

在程序執行的過程當中其值不能夠發生改變的量,Java中常量可分爲字面值常量和自定義常量。 eg. final double PI = 3.14;

  • 字符串常量     用雙引號括起來的內容
  • 整數常量       全部整數   12,23,默認爲int長整型加字母‘L ’
  • 小數常量       全部小數   12.34,56.7,默認爲都doublefloat加字母‘F’
  • Ø  字符常量       用單引號括起來的內容‘a’,‘A’,‘0’和轉義字符常量」\n」
  • 布爾常量       較爲特殊,只有true和false
  • 空常量         null (數組部分講解)
  • 符號常量       用一個標識符來表示的常量,修飾符final,eg. #define PI 3.14

f)     

 

\b

退格

\t

水平製表符Tab

\n

換行

\f

表格符

\r

回車

\'

單引號

\"

雙引號

\\

反斜線

表:經常使用轉義字符

 

整型常量的三種進製表示形式

  • 十進制整數,如12, -314, 0。
  • 八進制整數,要求以0開頭,如012
  • 十六進制數,要求0x或0X開頭,如0x12
  • 十進制數形式,必須含有小數點,例如:

f)      浮點類型常量兩種表示形式

3.14       314.0 時     .314

  • 科學記數法形式,如

3.14e2      3.14E2      314E2

g)     轉義字符的用法

  • System.out.println(「Hello\nWorld」);
  • System.out.println(「Hello」+」\n」+」World」);
  • 十進制和二進制的快速轉換利用8421碼;
  • 二進制和八進制、十六進制之間轉換以十進制做爲橋樑;
  • 二進制到八進制每3位一組合,二進制到十六進制,每4位一組合。

h)     進制轉換訣竅

i)       有符號數據表示方法

在計算機內,有符號數有3種表示法:原碼、反碼和補碼。全部數據的運算都是採用補碼進行的。

  • 原碼:就是二進制定點表示法,即最高位爲符號位,「0」表示正,「1」表示負,其他位表示數值的大小。
  • 反碼:正數的反碼與其原碼相同;負數的反碼是對其原碼逐位取反,符號位除外
  • 補碼:正數的補碼與其原碼相同;負數的補碼是在其反碼的末位加1

u  [+1] = [00000001] = [00000001] = [00000001]

u  [-1] = [10000001] = [11111110] = [11111111]

參考:

4.     運算符和表達式

表達式是由運算符與操做數組合而成的,運算符指明對操做數的運算方式。組成表達式的Java操做符有不少種。運算符按照其要求的操做數數目來分,能夠有單目運算符、雙目運算符和三目運算符,它們分別對應於1個、2個、3個操做數。運算符按其功能來分,有算術運算符、賦值運算符、關係運算符、邏輯運算符、位運算符和其餘運算符。

優先級

   

含義描述

1

( ) ,. , [ ]

強制運算、方法調用

2

++ , -- , + , ~(位取反) , !(邏輯取反)

一元運算、字符串相加

3

New   eg.Type a=new Type()

建立運算符

4

* , / , %

算術運算 乘除、取餘

5

+ , -

算術運算 加減(正負)

6

<< , >> , >>>(無符號)

位運算

7

< , > , <= , >= , instanceof

比較運算、類運算

8

= = , ! = , .equals()

比較運算

9

&

邏輯(位)運算 與

10

^

位運算 異或

11

|

邏輯(位)運算 或

12

&&

邏輯 與(短路)

13

||

邏輯 或(短路)

14

?:   eg. (關係表達式)?表達式1:表達式2

三元 條件運算

15

= , *= , /= , %= , += , -=

簡單賦值運算

16

<<= , >>=  , >>>= , &= , ^= , |=

複雜賦值運算

a)      算術運算符

* , / , % , + , - 

  • %:任何整數模2不是0就是1,因此只要改變被模數就能夠實現開關運算。
  • +:加法運算符,鏈接符。舉例:123+321+hello=444hello;hello+123+321=hello123321;hello+(123+321)=hello444;
  • ++,--:自增自減運算。舉例:int a=5;print(4++);//5 print(++4);//7
  • * , /:注意小數類型計算問題。1/2*2=0,1/2*2.0=0,1/2.0*2=1.0。整型與整型運算得整型,整形與浮點型運算得浮點型,結果取取決於第一次遇到浮點型的位置。

b)     賦值運算符

= , *= , /= , %= , += , -=

c)      比較運算符

< , > , <= , >= ,= = , ! = boolean bo=(i==j);

       特色:該運算符的特色是:運算完的結果,要麼是true,要麼是false。

待補充:==與.equals()區別:

d)     邏輯運算符

& , | , ^ , ! , && , ||

       邏輯運算符除了 !  外都是用於鏈接兩個boolean類型表達式。

  • &:只有兩邊都爲true結果是true。不然就是false。
  • |:只要兩邊都爲false結果是false,不然就是true。
  • ^:異或:和或有點不同。

u  兩邊結果同樣,就爲false;

u  兩邊結果不同,就爲true。

  • & 和 &&區別:

u  &:不管左邊結果是什麼,右邊都參與運算(建議短路與);

u  &&: 短路與,若是左邊爲false,那麼右邊不參數與運算。

  • | 和|| 區別:

u  |:兩邊都運算(建議短路或);

u  ||:短路或,若是左邊爲true,那麼右邊不參與運算。

e)     位運算符

用於操做二進制位的運算符;& , | , ^ ,<< , >> , >>>(無符號)

  • << :空位補0,被移除的高位丟棄。
  • >> :最高位是零,右移空位補0;最高位是1,最高位補1,其餘空位補0。
  • >>> :最高位不管是0或1,右移空位都補0。
  • & :任何二進制和0的 & 運算,結果都是0;和1的 & 運算,結果都是原值。
  • | :任何二進制和0的 | 運算,結果都是原值;和1的 | 運算,結果都是1。
  • ^ :任何相同二進制的 ^ 運算,結果都是0;不一樣的 ^ 運算,結果都是1。
  • 賦值表達式自己也是一個值,其值等於左值。舉例:int b = (a=6);得出b=6。

f)      表達式

待補充~

 

 

5、      流程控制

在Java中,流程控制分爲三種基本結構:順序結構、分支結構和循環結構。

If 判斷:

else If 判斷:

If 判斷(嵌套)

switch 判斷:

if (表達式) {

       //語句1;

} else {

       //語句2;

}

類比:

(關係表達式)?

表達式1:表達式2;

注:else語句可用

Continue代替;

if (表達式1) {

       //語句1;

}

else if (表達式2) {

           //語句2;

}

else {

//語句3;

}

If (表達式1) {

       if(表達式2) {

              //語句1;

       } else {

              //語句2;

       }

} else {

       //語句3;

}

switch (表達式) {

case 常量1:

語句1;

break;

case 常量2:

語句2;

break;

default:

語句3;

}

while循環:

do-while循環

for循環:

while(表達式) {

            //循環體;

}

do{

   //循環體;

} while(表達式);

for(初始化;條件;迭代) {

   //循環體;

}

           

1.     循環語句

a)      循環是相同動做的集合.

b)     循環次數肯定的狀況,一般選用for循環;

循環次數不肯定的狀況,一般選用while或do-while循環。

c)      初始狀況不知足循環條件時,while循環一次都不會執行;

do-while循環無論任何狀況都至少執行一次。

d)     for 循環,若變量在判斷條件內初始化,則做用域爲循環體(大括號)內。

e)     嵌套循環判斷條件:內層循環一圈,外層循環一次。

2.     判斷語句

a)      多重if與switch選擇結構比較

  • 相同點:都是用來處理多分支條件的結構
  • 不一樣點:switch選擇結構只能處理等值條件判斷的狀況;多重if選擇結構沒有switch選擇結構的限制,特別適合某個變量處於某個連續區間時的狀況。

b)     else If 順序進行判斷,當前麪條件不知足時才進行下一步,條件知足,跳過剩餘結構,結束判斷語句。

c)      switch 後面的小括號中的變量應該是int、short、byte、char、枚舉類型、String

d)     switch 可進行語句合併,以進行連續區間判斷。(省去語句和break)

3.     跳轉語句

a)      break:結束判斷語句,執行完判斷體後的語句後,終止離本身最近的外層循環。

 

do {

        String title = input.next();

        if (title.equals("exit")) {

       break;

        }

    } while (true); // 跳出死循環

b)     continue結束判斷語句,終止本次循環,不執行判斷體後面語句,進入下一次循環。

    public static void main(String[] args) {

    int i = 0;

    do {

        i++;

        if (i == 3) {

       // break; // 輸出12

       continue; // 輸出1245

        }

        System.out.println(i);

    } while (i < 5);

}

c)      return結束當前方法的執行並退出,並返回值到調用該方法的語句處

    for (int i = 0; i < 10; i++) {

        if (i % 2 != 0)

       return;

        System.out.print(i);

    } // 運行結果:0

4.     flag 或index標記的用法

  • 循環內判斷用flag標記返回判斷結果。
  • 返回函數返回值時,用flag傳遞返回值。
  • 須要交互輸入的函數最好放在測試類的main中,否者傳遞返回值會很麻煩。

 

 

6、      數組

數組是一個變量,存儲相同數據類型的一組數據

步驟

舉例

解釋

聲明

int[ ] a;

告訴計算機數據類型是什麼

分配空間

a = new int[5];

告訴計算機分配幾個連續的空間

賦值

a[0] = 8;

向分配的格子裏放數據

引用

a[0] = a[0] * 10;

引用數據進行計算

 

 

 

 

 

 

1.     數組的經常使用操做

a)     聲明數組並分配空間

數據類型[ ] 數組名 =  new 數據類型[大小];   

b)     數組的初始化(聲明的同時賦值)

  • 方法1: 邊聲明邊賦值。

int[ ] scores = {89, 79, 76};

int[ ] scores = new int[ ]{89, 79, 76};

  • 方法2:動態地從鍵盤錄入信息並賦值。

Scanner input = new Scanner (System.in);

for (int i = 0; i < 30; i ++) {

scores[i] = input.nextInt ();}

  • 建立數組並賦值的方式在一條語句中完成。
  • 全部的數組下標默認從0開始,並且訪問時不可超出定義的上限,不然會產生越界錯誤。
  • for 遍歷 (逆序輸出)

c)     數組的遍歷

for (int k = array.length - 1; k >= 0; k--) {// 逆序輸出

    System.out.print(array[k] + "\t");

}

  • for加強型函數

for (int temp : array) {// 用for加強型函數對數組進行順序輸出

    System.out.println(temp);

}

  • 對數組進行增添,修改,刪除

數組的增添舉例

String[] phones = new String[] {"iPones4S", "iPones5", null};

// null 不用加雙引號

int index = -1;// 增長監視器

for (int i = 0; i < phones.length; i++) {// 1.增長iPones6

    if (phones[i] == null) {

        index = i;

        break;

    }

}

    if (index != -1) {

        phones[index] = "iPones6";

    } else {

        System.out.println("數組已滿");

        }

System.out.println(Arrays.toString(phones));

註釋:數組的修改與刪除相似

d)     數組的排序

  • 冒泡排序

for (int m = 0; m < array.length - 1; m++) { // 冒泡排序

            for (int n = 0; n < array.length - 1 - m; n++) {

                if (array[n] > array[n + 1]) {

                    int temp = array[n];

                    array[n] = array[n + 1];

                    array[n + 1] = temp;

                }

            }

        }

e)     使用Arrays 類操做數組

方法名稱

說明

Arrays.

boolean equals(array1,array2)

比較array1和array2兩個數組是否相等

sort(array)

對數組array的元素進行升序排列

String toString(array)

將一個數組array轉換成一個字符串

void fill(array,val)

把數組array全部元素都賦值爲val

copyOf(array,length)

把數組array複製成一個長度爲length

的新數組,返回類型與複製的數組一致

int binarySearch(array, val)

查詢元素值val在數組array中的下標

(要求數組中元素已經按升序排列

註釋:import java.util.*;

2.     二維數組

1、         數組的初始化

    String[][] str = new String[5][];

    int[][] scores = new int[][] { { 90, 85, 54 }, { 76, 80 },{ 87 } };

    int[][] scores = { { 90, 85, 54 }, { 76, 80 }, { 87 } };

2、         數組的遍歷

public class Case5 { // 二維數組的遍歷

        public static void main(String[] args) {

            int[][] scores = new int[][] { { 90, 78, 54 }, { 76 , 80 }, { 87 } };

            for (int i = 0; i < scores.length; i++) { //外層數組長度

                for (int j = 0; j < scores[i].length; j++) {//內層數組長度

                    System.out.println(scores[i][j]);

                }

            }

        }

    }

 

 

 

Java 面向對象

1、        前言

1.      理解面向對象

  • 面向對象是相對面向過程而言
  • 面向過程強調的是功能行爲
  • 面向對象將功能封裝進對象,強調具有了功能的對象。
  • 開發的過程:其實就是不斷的建立對象,使用對象,指揮對象作事情。
  • 設計的過程:其實就是在管理和維護對象之間的關係。
  • 封裝(encapsulation)
  • 繼承(inheritance)
  • 多態(polymorphism)
  • 類:是具備相同屬性和方法的一組對象的集合。
  • 對象:用來描述客觀事物的一個實體,由屬性和方法構成。
  • 類是對象的抽象,對象是類的具體實例。
  • 類是抽象的,不佔用內存,而對象是具體的,佔有內存空間。

2.      面向對象的特色

2、        類和對象

1.     類和對象的定義

public class ConstructorMethod {

    String name;

int age; // 成員變量

public ConstructorMethod(String name, int age) {

//有參構造方法,構造方法無返回類型

        this.name = name;                          

        this.age = age;  //實例的屬性 = 實參;

}

    public static int Case1() { //成員方法

        System.out.println("我是Case1調用");

        return 0;

    }

}

2.     類的建立和使用

a)     類的定義

  • 訪問修飾符 class 類名 {成員變量;成員方法}      // 詳見上例
  • 引用類的屬性:對象名.屬性

b)     類的使用

舉例:center.name = "北京中心";     //給name屬性賦值

  • 引用類的方法:對象名.方法名()

舉例:center.showCenter();     //調用showCenter()方法

c)     補充說明

  • 在Java中,類是按須加載,只有當須要用到這個類的時候,纔會加載這個類,而且只會加載一次。
  • 一個類文件中Public類只有一個,且和類文件同名。且類的訪問權限只有Public和Default,包內都可見,故包內類不可同名。
  • 類名 對象名= new 類名();

3.     對象的建立和使用

a)     對象的建立

舉例:School center = new School();

b)     對象的使用

  • 用對象名引用類的屬性和方法。參見類的使用。
  • 類名 對象名= new 類名();        //對象的聲明與初始化
  • 數據類型 變量名 = new 數據類型(值);       //變量的聲明與初始化
  • 對象名和變量名都是一種引用。數據類型能夠當作一種特殊的類。在此概念下,變量和對象的特性可部分通用。
  • 成員變量:在類的範圍內聲明,在類的整個範圍內都能用,相似C語言中全局變量
  • 局部變量:在局部(方法體內)聲明,大括號(或循環體)限制局部變量的做用域。
  • 數據類型 變量名 = 值;或 數據類型 變量名 = new 數據類型(值);
  • 第二種聲明方式通常不用,本文引入主要是爲了與對象的定義進行對比。
  • 局部變量在使用前必須賦初始值。成員變量即便沒有賦初始值,系統會自動初始化,

d)     對象和變量的幾點思考

4.     成員變量VS局部變量

a)     定義

b)     變量的聲明與初始化

c)     使用規則

基本數據類型爲初始化爲0,布爾類型爲false,引用類型爲null。

  • 局部變量和成員變量能夠同名,同名時,就近使用。
  • Java沒有全局變量的概念。概念相近的有靜態變量。

public class Test {

    public static void main(String[] args) {

    Cat cat = null;  //局部變量須要初始化或傳實參

    Pet pet = new Cat();

    cat = (Cat)cat;

    }

}

 

class Pet {

}

 

class Cat extends Pet {

}

5.     成員方法VS方法

a)     定義

  • 所謂方法,就是能夠重複使用的一段代碼的組合,是一個功能模塊。成員方法是定義在類內部的方法。

通常格式:訪問修復符 返回值類型 方法名(參數列表){方法體};

  • 訪問修飾符:方法容許被訪問的權限範圍, 能夠是 public、protected、private 甚至能夠省略。
  • 返回值類型:方法返回值的類型。若是方法不返回任何值,則returnValueType的值爲 void ;若是方法返回值不爲void,則須要指定返回值的類型,而且在方法體中使用 return 語句返回值。
  • 方法名:定義的方法的名字,必須使用合法的標識符
  • 參數列表:傳遞給方法的參數列表,參數能夠有多個,多個參數間以逗號隔開,每一個參數由參數類型和參數名組成,以空格隔開。定義時的參數成爲形參,須定義數據類型。調用時的參數稱爲實參,實參不用定義數據類型。
  • 方法體:方法體包含定義哪些方法語句的集合。
  • 語句語句必須寫在方法體內,除初始化語句。

b)     訪問修飾符

類的訪問權限有Public和Default兩種,類中成員的訪問權限有下列四種:

  • Public: 能訪問該類的任何地方能夠訪問Public成員。
  • Protected:(子類修飾符)包內,和包外自身從父類繼承而來的受保護成員。
  • Default:(包修飾符)包內成員可相互訪問。
  • Private:(私有修飾符)只有本身類內的成員能夠訪問。
  • Ø  訪問權限由大到小:public>protected>default>private
 
   


補充:繼承權限測試. Package

繼承權限測試(類之間)  & 訪問權限測試(屬性和方法)測試結果:

  • Ø  訪問修飾符是限制要訪問(繼承)本身的對象權限的符號
  • Ø  應用範圍:

類的訪問修飾符只有public和默認兩種。

類中成員 public(公共修飾符) --> protected(子類) --> default(包)--> private(私有)

局部變量做用域肯定,故沒有訪問修飾符,訪問修飾符僅針對成員變量和方法。

  • Ø  訪問方式:

子類對父類的訪問,直接調用屬性或方法(其實隱含this.調用)

 非繼承關係或父類對子類的訪問的訪問方式,需用對象或類名訪問。

  • Ø  應用原理:

訪問權限是基於繼承決定的,繼承權限也是一種訪問權限。

繼承則屬性和方法歸父類和子類共有,但除私有成員不能夠訪問。

子類能夠選擇重寫父類的屬性和方法的訪問修飾符,權限不能小於父類

c)     方法的調用

  • 在同一個包裏,普通方法須要用對象名調用,靜態(類)方法能夠直接類名調用(同一類甚至不用寫類名)。

d)     方法的重載

方法重載,就是在同一個類裏中能夠建立多個方法,方法名要同樣,參數列表不一樣,和訪問修飾符 、返回值無關。調用方法時經過傳遞給它們的不一樣參數個數和參數類型來決定具體使用哪一個方法,是一個類中多態性的一種表現。

方法重寫,在子類和父類之間對,父類的函數進行從新定義。子類名稱和參數別表與父類相同,方法體重寫。

6.     構造方法

所謂構造方法,就是構造對象的方法,經過new + 構造方法, 這樣就建立了一個新的對象。

  • 構造方法要與類名相同,無返回類型。在建立對象的時候,對象的屬性進行初始化,減小初始化語句。
  • 每個類都有構造方法,在沒有定義時,系統默認建立一個無參構造方法。
  • 構造方法是一類特殊的方法,在定義和調用具備普通方法的特性。
  • 成員變量包括實例變量和類(靜態)變量;而成員方法包括實例方法、類(靜態)方法。
  • 類變量、類方法是屬於類的變量、方法,必須是靜態的,要加static;故其又稱靜態變量、靜態方法。能夠不用實例,直接用類就能夠訪問或調用類變量或類方法。
  • 實例變量和實例方法在一個類中沒有static修飾,使用變量或方法時候先實例化(建立對象)才能訪問或調用實例變量或實例方法;
  • 方法與變量是個整體性概念,定義在類內部的被稱爲成員變量與成員方法,定義在main方法或方法體內部的變量被稱爲局部變量。
  • 實例方法引用this指向正在執行方法的類的實例,構造方法引用this指正在的構造對象,靜態方法不能使用this和supper關鍵字,構造方法根據不一樣參數指向類的實例。
  • super()或者this()都是調用構造函數,構造函數用於初始化,因此初始化的動做要先完成。
  • super() super. 只能在子類裏使用。

7.     補充幾點

a)     變量幾個概念的解析

b)     this和supper的用法

public class Test {

    private String name;

    public Test(){

       this.name = "小新";

    }

    public Test(String name) {

       System.out.println("我是" +this.name);

    }

    public static void main(String[] args) {

       Test test = new Test("小強");

    }

} //運行結果:我是null(實參沒有該成員變量賦值)

c)     main 方法

public class Test {

    public static void main(String[] args) {

    for (int i = 0; i < args.length; i++) {

        System.out.println("args" + i + "=" + args[i]);

    }

    }

}

輸出結果:

args0=args1

args1=args2

  • Public:表示的這個程序的訪問權限,表示的是任何的場合能夠被引用,這樣java虛擬機就能夠找到main()方法,從而來運行javac程序。
  • Static:代表方法是靜態的,不依賴類的對象的,是屬於類的,在類加載的時候main()方法也隨着加載到內存中去。若是主函數設置成非靜態,則沒法運行。或實例化主方法。
  • Void:main()方法是不須要返回值的。
  • Main:做爲程序的入口,有main方法程序才能運行。
  • args[]:是用來從控制檯接收參數。
  • 靜態方法內不能夠調用非靜態屬性,若要調用非靜態成員屬性,則須要把屬性設置成靜態屬性。或者把把非靜態成員單獨封裝成方法,再經過方法調用
  • 方法體內部只可定義語句,不可再定義方法。
  • 參數的聲明
  • 接收實參的幾種形式

d)     方法傳參

u  int month = 4;   

u  int day = input.nextInt();

注:做爲形參的變量的初始化即是傳入實參。

 

待補充~

e)     內部類

內部類將相關的類組織在一塊兒,從而下降了命名空間的混亂。一個內部類能夠定義在另外一個類裏,能夠定義在函數裏,甚至能夠做爲一個表達式的一部分。內部類能夠直接訪問外部類中的成員。而外部類想要訪問內部類,必需要創建內部類的對象。

http://blog.sina.com.cn/s/blog_accab4a90101gzh2.html

①       匿名內部類

匿名內部類也就是沒有名字的內部類,正由於沒有名字,因此匿名內部類只能使用一次,它一般用來簡化代碼編寫。但使用匿名內部類還有個前提條件:必須繼承一個父類或實現一個接口。

abstract class Person {

    public abstract void eat();

}

 

public class Demo {

    public static void main(String[] args) {

    Person p = new Person() {

        public void eat() {

       System.out.println("eat something");

        }

    };

    p.eat();

    }

}

h)     Static關鍵字

  • 想要實現對象中的共性數據的對象共享。能夠將這個數據進行靜態修飾。
  • 被靜態修飾的成員,能夠直接被類名所調用。也就是說,靜態的成員多了一種調用方式。類名.靜態方式。
  • 靜態隨着類的加載而加載。並且優先於對象存在。
①       靜態代碼塊

一個類可使用不包含在任何方法體中的靜態代碼塊,當類被載入時,靜態代碼塊被執行,且只被執行一次,靜態塊經常使用來執行類屬性的初始化。

    static {

        System.out.println ("Hello Everyone");

        }

方法裏不能夠定義static

待補充~

i)       final關鍵字

這個關鍵字是一個修飾符,能夠修飾類,方法,變量。

  • 被final修飾的類是一個最終類,不能夠被繼承。
  • 被final修飾的方法是一個最終方法,不能夠被覆蓋(重寫)。
  • Ø  被final修飾的變量是一個常量,只能賦值一次。

3、      封裝、繼承和多態

1.     封裝

public class Test {

    private String name; //將類的屬性進行封裝

    public String getName() { //並提供可帶判斷條件的訪問方法

        return name;

}

 

    public void setName(String name) {

        this.name = name;

}

}

 

a)     定義

將類的屬性隱藏在類內部,不容許外部程序直接訪問,而是經過該類提供的方法來實現對隱藏信息的操做和訪問。

b)     步驟

修改屬性的可見性(設爲private,防止錯誤的修改)à建立公有的getter/setter方法(用於屬性的讀寫)à在getter/setter方法中加入屬性控制語句(對屬性值的合法性進行判斷)。

c)     優勢

  • 封裝確實可使咱們容易地修改類的內部實現,而無需修改使用了該類的客戶代碼。
  • 能夠對成員變量進行更精確的控制。
  • 限制對屬性的不合理操做;
  • 結合權限控制,限制客戶端的操做權限。

2.     繼承

class Person {                      // 父類

    private String name;

    public static int age;

    public static String sex;

 

    public Person() {              // 會自動生成無參構造器

          System.out.println("父類構造器");                        

    };                              // 可是考慮繼承的可靠性,建議寫上。

 

    public void setName(String name) {

        this.name = name;

    }

 

    public String getName() {

        return this.name;

    }

}

 

class Student extends Person {   // 子類

    private String school;

 

    public Student() {            // 子類student中構造

        super();                   //super只可在子類中使用

        System.out.println("子類構造器");

    }

}

public class TestExtendDemo {    // 測試類

    public static void main(String[] args) {

        Person.age = 18;

        Student.age = 19;          // 繼承父類的成員屬性和方法可直接調用

        Person.sex = "男";         // 靜態變量或方法用類調用

        System.out.println(Student.age+Person.sex);

        Scanner input = new Scanner(System.in);

        Student someone = new Student();    //建立子類對象的過程

        someone.setName(input.next());      // 實例變量和方法用實例調用

        System.out.println(someone.getName());

    }

}

a)     定義

繼承是面向對象最顯著的一個特性。多個類中存在相同屬性和方法時,將這些內容抽取到單獨一個類中,那麼多個類無需再定義這些屬性和方法,只要繼承那個類便可。繼承是代碼重用的一種方式。Java經過extends關鍵字來實現單繼承。(Is a)

b)     繼承的基本原則

  • 可以繼承除構造方法外全部成員,但private成員不能夠訪問;
  • 能夠同經過super()調用類的構造方法,已提升代碼重用性。一樣super()能夠調用父類的成員屬性和成員方法。
  • Java具備單根繼承性,只能繼承一個父類。
  • Java繼承具備傳遞性,支持多級繼承。
  • Object類是全部類的父類。
  • 聲明:[訪問修飾符] class Dog extendsPet {   //子類特有的屬性和方法}
  • 調用父類構造方法:super(); super(name);

c)     格式與引用

訪問父類屬性:super.name;

調用父類方法:super.print();

d)     補充幾點

  • 父類沒有無參構造器,則需在子類構造器的第一行顯式調用父類的有參構造器。

緣由:子類的全部構造器中的第一行,其實都有一條隱身的語句super(), super()表示調用父類的無參構造器。子類繼承父類中的屬性,在new 子類的時候,相應的父類的屬性也就拿到了,這就是子類的實例化過程。

然而父類有有參構造器,則無參構造器就不存在了,因此在子類中須在第一行顯式調用super(參數),或者在父類中添加一個無參構造器。之因此須在第一行調用,是由於父類的構造器調用以及初始化過程必定在子類的前面。

而且,父類也被new一個對象出來的說法是錯誤的,舉例抽象類能夠被繼承的,但抽象類不能被實例化。

  • 隱藏和覆蓋的區別:

參考:Java中屬性的隱藏與方法的覆蓋的區別

參考:靜態綁定與動態綁定

  • 方法重寫的原則:

u  子類方法重寫時方法名、參數、返回值、返回類型均須相同。訪問權限不小於父類。

解析:確保子類能夠重寫父類。父類不能覆蓋子類。

u  重寫是父子類要麼都靜態,要麼都不靜態。

u  子類能夠定義與父類同名的靜態方法,以便在子類中隱藏父類的靜態方法。

u  父類的私有方法不可訪問,不能被子類重寫。

 

3.     多態

abstract class Animal { // 由於自己實例化沒有意義,因此通常申明爲抽象類

    Animal() {           // 會自動生成無參構造器

    };                    // 可是考慮繼承的可靠性,建議寫上。

 

    abstract void eat();//  抽象方法

}

class Cat extends Animal {      // 一、繼承父類

    public void eat() {         // 二、子類方法的重寫

        System.out.println("吃魚");

    }

 

    public void catchMouse() {  //子類私有方法,只能用子類對象調用

        System.out.println("抓老鼠");

    }

}

 

class Dog extends Animal {       // 一、繼承父類

    public void eat() {          // 二、子類方法的重寫

        System.out.println("吃骨頭");

    }

 

    public void kanJia() {

        System.out.println("看家");

    }

}

 

class DuoTaiDemo {                // 類名與源文件相同,不然沒法運行

    public static void main(String[] args) {

        function(new Cat());      // new Cat() 表示構造一個貓的對象

        function(new Dog());

 

        //Animal a;          //對象可像變量同樣聲明和傳遞參數

        //a= new Cat();     //父類爲抽象類,不能實例化,但能建立引用

        Animal a=new Cat();

        // 向上轉型 // 相似變量傳參,new Cat()是參數

        a.eat();      

        //3.父類對象引用指向子類對象 PS:須先知足前兩個條件

    }

 

   public static void function(Animal a) {   //對象可做變量傳遞參數

        a.eat();       //3.父類對象引用指向子類對象 PS:須先知足前兩個條件

       

        if (a instanceof Cat) {// 用於判斷對象是否爲指定類的實例

            Cat c = (Cat) a;    // 向下轉型,由Animal(父)類轉爲Cat(子)類

            c.catchMouse();     // 向下轉型,調用子類特有屬性

        } else if (a instanceof Dog) {

            Dog c = (Dog) a;

            c.kanJia();

        }

    }

 

public class Polymorphism {  // 多態傳參 ,取例 Think in Java

    void doStuff(Shape s) {  // 形參

    s.erase();

    // ...

    s.draw();

    }

 

    public static void main(String[] args) {

 

    Circle c = new Circle();  // Circle/Triangle/Line是Shape的子類

    Triangle t = new Triangle();

    Line l = new Line();

    doStuff(c); // 實參

    doStuff(t);

    doStuff(l);

    }

}

a)     定義

指容許不一樣類的對象對同一消息作出響應。即同一消息能夠根據發送對象的不一樣而採用多種不一樣的行爲方式。(發送消息就是方法調用),與方法不一樣的是對象的屬性則不具備多態性。

b)     實現技術

動態綁定:是指在程序運行時判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法,是多態實現的具體形式。執行動態綁定的非靜態方法

補充知識:靜態綁定:又稱爲前期綁定在程序編譯時進行了綁定,即在還沒運行時,就已經加載到內存。執行靜態綁定的有變量和靜態方法

c)     必要條件

  • 要有繼承(實現多態的前提);
  • 要有重寫(實現多態的基礎);
  • 父類引用指向子類對象

d)     實現方式

接口實現,繼承父類進行方法重寫,同一個類中進行方法重載。當使用多態方式調用方法時,首先檢查父類中是否有該方法,若是沒有,則編譯錯誤;若是有,再去調用子類的該同名方法。

e)     做用

消除類型之間的耦合關係

f)      補充幾點

  • 多態在子父類中的成員上的體現的特色:(待進一步完善)

u  成員變量:在多態中,子父類成員變量同名。

在編譯時期:參考的是引用型變量所屬的類中是否有調用的成員。(編譯時不產生對象,只檢查語法錯誤)

運行時期:也是參考引用型變量所屬的類中是否有調用的成員。

簡單一句話:不管編譯和運行,成員變量參考的都是引用變量所屬的類中的成員變量。再說的更容易記憶一些:成員變量à編譯運行都看 = 左邊。

u  靜態函數

編譯時期:參考的是引用型變量所屬的類中是否有調用的成員。

運行時期:也是參考引用型變量所屬的類中是否有調用的成員。

爲何是這樣的呢?由於靜態方法,其實不屬於對象,而是所屬於該方法所在的類。

調用靜態的方法引用是哪一個類的引用調用的就是哪一個類中的靜態方法。

簡單說:靜態函數à編譯運行都看 = 左邊。

u  成員函數

編譯時期:參考引用型變量所屬的類中是否有調用的方法。

運行事情:參考的是對象所屬的類中是否有調用的方法。

爲何是這樣的呢?由於在子父類中,對於如出一轍的成員函數,有一個特性:覆蓋。

簡單一句:成員函數,編譯看引用型變量所屬的類,運行看對象所屬的類。

更簡單:成員函數à編譯看 = 左邊,運行看 = 右邊。

 

4、      抽象類和接口

1.     抽象類(abstract)

public abstract class ClassName {

    int name;

    abstract void fun();

}

a)     定義

  • 抽象類:被定義爲抽象的類,它用來集合子類的通用特性的。不能被實例化,只能被用做子類的超類。
  • 抽象方法:它只有聲明,而沒有具體的實現,若是一個類含有抽象方法,則稱這個類爲抽象類。抽象方法聲明格式爲:abstract void fun();由於抽象類中含有無具體實現的方法,因此不能用抽象類建立對象。
  • 抽象類就是爲了繼承而存在的,若是定義一個抽象類,不去繼承它,沒有任何意義。
  • 抽象方法必須爲public或者protected(由於若是爲private,則不能被子類繼承,子類便沒法實現該方法),缺省狀況下默認爲public。
  • 抽象類能夠沒有抽象方法,也能夠所有是抽象方法,若是子類繼承的父類是抽象類,則繼承父類全部非私有方法,又因爲存在抽象類的方法爲抽象方法,故子類必須重寫父類裏全部的抽象的方法(除非父類抽象類沒有抽象方法),才能被實例化,也就是建立對象,要否則子類也將是個abstract類,不能被實例化。
  • 抽象類中能夠有非抽象的構造方法,建立子類的實例時可能調用。

b)     特色

2.     接口(interface)

public interface InterfaceName {

    public abstract void cry();

}

    class ClassName implements Interface1,Interface2....{

}

a)     定義

在軟件工程中,接口泛指供別人調用的方法或者函數。從這裏,咱們能夠體會到Java語言設計者的初衷,它是對行爲的抽象。

接口是抽象方法的集合。若是一個類實現了某個接口,那麼它就繼承了這個接口的抽象方法。這就像契約模式,若是實現了這個接口,那麼就必須確保使用這些方法。

接口主要用來描述類具備什麼功能,自身不能作任何事情。具體實現交由實現接口的那個類來完成。

b)     特色

  • 接口中能夠聲明變量,且被隱式地指定爲public static final變量。可當作全局常量用。
  • 接口是對方法的抽象,定義的方法必須是抽象方法。系統默認都是public abstract
  • 接口不能夠實例化。
  • 實現類且必須實現全部的接口。若是不能所有實現,則定義兩個接口。
  • 接口也能夠extends接口
  • 接口回調:是指能夠把使用某一接口的類建立的對象的引用賦給該接口聲明的接口變量,那麼該接口變量就能夠調用被類實現的接口的方法。實際上,當接口變量調用被類實現的接口中的方法時,就是通知相應的對象調用接口的方法,這一過程稱爲對象功能的接口回調。     參考:http://blog.csdn.net/hack_bug/article/details/7625646
  • 若是須要從子類向基類進行向上轉型,則使用基類,不然可以使用組合關聯。
  • 若是你想實現多重繼承,那麼你必須使用接口。因爲Java不支持多繼承,子類不可以繼承多個類,但能夠實現多個接口。所以你就可使用接口來解決它。
  • 若是基本功能在不斷改變,那麼就須要使用抽象類。若是不斷改變基本功能而且使用接口,那麼就須要改變全部實現了該接口的類。

c)     其餘幾點補充

d)     何時使用抽象類和接口

3.     抽象類和接口的對比

a)     語法層面的區別

參數

抽象類

接口

默認的方法實現

它能夠有默認的方法實現

全部的方法都是抽象的。不存在方法的實現

實現

子類使用extends關鍵字來繼承抽象類。若是子類不是抽象類的話,它須要提供抽象類中全部聲明的方法的實現。

子類使用關鍵字implements來實現接口。它須要提供接口中全部聲明的方法的實現

構造器

抽象類有構造器,用於子類初始化

接口不能有構造器

普通類

除了不能實例化抽象類以外,它和普通Java類沒有任何區別

接口是徹底不一樣的類型

訪問修飾符

抽象方法能夠有public、protected和default這些修飾符

接口方法默認修飾符是public。不可使用其它修飾符。

main方法

抽象方法能夠有main方法而且咱們能夠運行它

接口沒有main方法,所以咱們不能運行它。

多繼承

抽象方法能夠繼承一個類和實現多個接口

接口只能夠繼承一個或多個其它接口

速度

它比接口速度要快

接口是稍微有點慢的,由於它須要時間去尋找在類中實現的方法。

添加新方法

若是你往抽象類中添加新的方法,你能夠給它提供默認的實現。所以你不須要改變你如今的代碼。

若是你往接口中添加方法,那麼你必須改變實現該接口的類。

b)     設計層面上的區別

抽象類是對一種事物的抽象,即對類抽象,而接口是對行爲的抽象。抽象類是對整個類總體進行抽象,包括屬性、行爲,可是接口倒是對類局部(行爲)進行抽象。舉個簡單的例子,飛機和鳥是不一樣類的事物,可是它們都有一個共性,就是都會飛。那麼在設計的時候,能夠將飛機設計爲一個類Airplane,將鳥設計爲一個類Bird,可是不能將 飛行 這個特性也設計爲類,所以它只是一個行爲特性,並非對一類事物的抽象描述。此時能夠將 飛行 設計爲一個接口Fly,包含方法fly( ),而後Airplane和Bird分別根據本身的須要實現Fly這個接口。而後至於有不一樣種類的飛機,好比戰鬥機、民用飛機等直接繼承Airplane便可,對於鳥也是相似的,不一樣種類的鳥直接繼承Bird類便可。從這裏能夠看出,繼承是一個 "是否是"的關係,而 接口 實現則是 "有沒有"的關係。若是一個類繼承了某個抽象類,則子類一定是抽象類的種類,而接口實現則是有沒有、具有不具有的關係,好比鳥是否能飛(或者是否具有飛行這個特色),能飛行則能夠實現這個接口,不能飛行就不實現這個接口。

設計層面不一樣,抽象類做爲不少子類的父類,它是一種模板式設計。而接口是一種行爲規範,它是一種輻射式設計。什麼是模板式設計?最簡單例子,你們都用過ppt裏面的模板,若是用模板A設計了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,若是它們的公共部分須要改動,則只須要改動模板A就能夠了,不須要從新對ppt B和ppt C進行改動。而輻射式設計,好比某個電梯都裝了某種報警器,一旦要更新報警器,就必須所有更新。也就是說對於抽象類,若是須要添加新的方法,能夠直接在抽象類中添加具體的實現,子類能夠不進行變動;而對於接口則不行,若是接口進行了變動,則全部實現這個接口的類都必須進行相應的改動。

5、     

 
   


異常

1.     JAVA異常

Java異常處理的目的是提升程序的健壯性。你能夠在catch和finally代碼塊中給程序一個修正機會,使得程序不因不可控制的異常而影響程序的流程。同時,經過獲取Java異常信息,也爲程序的開發維護提供了方便。

a)     概念解析

  • Java中的異經常使用對象來表示。
  • Java異常處理經過5個關鍵字try、catch、throw、throws、finally進行管理。
  • 異常是針對方法來講的,拋出、聲明拋出、捕獲和處理異常都是在方法中進行的。
  • Throwable: 有兩個重要的子類:Exception(異常)和 Error(錯誤),兩者都是 Java 異常處理的重要子類,各自都包含大量子類。
  • Error(錯誤):表示僅靠程序自己沒法恢復的嚴重錯誤。
  • Exception(異常):表示程序自己能夠處理的異常。
  • RuntimeException:是那些可能在 Java 虛擬機正常運行期間拋出的異常的超類。Java編譯器不去檢查它。這種異常能夠經過改進代碼實現來避免。
  • ThreadDeath:
  • 運行時異常:

b)     運行時異常和受檢查異常

RuntimeException類及其子類都被稱爲運行時異常,這種異常的特色是Java編譯器不去檢查它,也就是說,當程序中可能出現這類異常時,即便沒有用try...catch語句捕獲它,也沒有用throws字句聲明拋出它,仍是會編譯經過。

  • 受檢查異常:

除了RuntimeException類及其子類外,其餘的Exception類及其子類都屬於受檢查異常,這種異常的特色是要麼用try...catch捕獲處理,要麼用throws語句聲明拋出,不然編譯不會經過。

  • 二者的區別

運行時異常表示沒法讓程序恢復運行的異常,致使這種異常的緣由一般是因爲執行了錯誤的操做。

受檢查異常表示程序能夠處理的異常。受檢查異常表示程序能夠處理的異常。若是拋出異常的方法自己不處理或者不能處理它,那麼方法的調用者就必須去處理該異常,不然調用會出錯,連編譯也沒法經過。

固然,這兩種異常都是能夠經過程序來捕獲並處理的,好比除數爲零的運行時異常。

2.     處理異常機制

異常處理機制爲:拋出異常,捕捉異常。

  • 捕捉異常:在方法中用try...catch語句捕獲並處理異常,catach語句能夠有多個,用來匹配多個異常。
  • 拋出異常:對於處理不了的異常或者要轉型的異常,在方法的聲明處經過throws語句拋出異常。
  • Java規定:對於全部的可查異常,一個方法必須捕捉,或者聲明拋出方法以外。

3.     捕獲異常try / catch 和 finally

import java.util.InputMismatchException;

import java.util.Scanner;

 

public class TryCatch {

    public static void main(String[] args) {

    Scanner input = new Scanner(System.in);

 

    try {// 可能會發生異常的程序代碼

        System.out.print("請輸入一個數字:");

        int a = input.nextInt();

    } catch (InputMismatchException e) {// 捕捉異常

        System.err.println("數據類型不符!");

        e.printStackTrace();

        System.err.println(e.getMessage());

        // return; 若捕捉到異常會先執行finally, 再return。

    } catch (Exception e) {// catch 先寫子類,再寫父類

        System.out.println("再捕捉一次!");

        System.exit(1);

    } finally {// 除非執行System.exit(1),不然都會執行

        System.out.println("finally 被執行!");

        // 應用舉例:確保關閉數據庫,關閉流

    }

 

    System.out.println("我仍是被執行了!");

    // 若是提早return,則不執行了

    }

}

4.     拋出異常 throws和throw

public class Throws {

 

    public static void main(String[] args) throws Exception{

    System.out.println(10 / 0);

    throw new Exception("拋出異常");

    //System.out.println("throw後面的代碼再也不執行");

    }

}

5.     Java常見異常

a)     runtimeException子類:

  • Ø  java.lang.ArrayIndexOutOfBoundsException

數組索引越界異常。當對數組的索引值爲負數或大於等於數組大小時拋出。

  • Ø  java.lang.ArithmeticException

算術條件異常。譬如:整數除零等。

  • Ø  java.lang.NullPointerException

空指針異常。當應用試圖在要求使用對象的地方使用了null時,拋出該異常。譬如:調用null對象的實例方法、訪問null對象的屬性、計算null對象的長度、使用throw語句拋出null等等

  • Ø  java.lang.ClassNotFoundException

找不到類異常。當應用試圖根據字符串形式的類名構造類,而在遍歷CLASSPAH以後找不到對應名稱的class文件時,拋出該異常。

  • java.lang.NegativeArraySizeException數組長度爲負異常
  • java.lang.ArrayStoreException數組中包含不兼容的值拋出的異常
  • java.lang.SecurityException安全性異常
  • java.lang.IllegalArgumentException非法參數異常
  • Ø  IOException操做輸入流和輸出流時可能出現的異常。
  • EOFException文件已結束異常
  • FileNotFoundException文件未找到異常
  • ClassCastException類型轉換異常類
  • ArrayStoreException數組中包含不兼容的值拋出的異常
  • SQLException操做數據庫異常類
  • NoSuchFieldException字段未找到異常
  • NoSuchMethodException方法未找到拋出的異常
  • NumberFormatException字符串轉換爲數字拋出的異常
  • StringIndexOutOfBoundsException字符串索引超出範圍拋出的異常
  • IllegalAccessException不容許訪問某類異常
  • InstantiationException當應用程序試圖使用Class類中的newInstance()方法建立一個類的實例,而指定的類對象沒法被實例化時,拋出該異常

b)     IOException

c)     其餘

6.     自定義異常

待補充~

7.     Java異常處理的原則和技巧

  • 避免過大的try塊。
  • 不要把本身能處理的異常拋給別人。
  • catch塊儘可能保持一個塊捕獲一類異常
  • 細化異常的類型,不要無論什麼類型的異常都寫成Excetpion。
  • 不要用try...catch參與控制程序流程,異常控制的根本目的是處理程序的非正常狀況。

8.     補充幾點

若是出現異常的線程爲主線程,則整個程序運行終止;若是非主線程,則終止該線程,其餘線程繼續運行。

若是父類或者接口中的方法沒有拋出過異常,那麼子類是不能夠拋出異常的,若是子類的覆蓋的方法中出現了異常,只能try不能throws。

若是這個異常子類沒法處理,已經影響了子類方法的具體運算,這時能夠在子類方法中,經過throw拋出RuntimeException異常或者其子類,這樣,子類的方法上是不須要throws聲明的。

越早處理異常消耗的資源和時間越小,產生影響的範圍也越小。

      

6、      面向對象的幾點猜測

Java 高級特性

1、        集合框架和泛型

1.     集合 框架 API

       大多集合可以處理任何類型的數據,由於這些集合定義的處理對象使用了Object類型。

全部的Java集合都在java.util包中。

       上述類圖中,實線邊框的是實現類,好比ArrayList,LinkedList,HashMap等,折線邊框的是抽象類,好比AbstractCollection,AbstractList,AbstractMap等,而點線邊框的是接口,好比Collection,Iterator,List等。

 

 

 

 

 

 

 

 

Java 集合框架

接口

實現類

是否有序

是否容許元素重複

特色

Collection

Collection

無序

不惟一

父接口

List

ArraysList

有序

不惟一

遍歷訪問效率高[Z1] 

LinkedList

有序

不惟一

插入刪除效率高

Set

AbstractSet

無序

惟一

 

HashSet

查找效率高

Map

TreeSet

二叉排序樹

key必須惟一
value能夠重複

 

AbstractMap

 

HashMap

查詢指定元素效率高

TreeMap

二叉排序樹

 

a)     Collection 接口抽象方法:(List、Set 、Map實現接口)

返回類型

方法

解釋

boolean

add(E e)

確保此 collection 包含指定的元素(可選操做)。

void

clear()

移除此 collection 中的全部元素(可選操做)。

boolean

contains(Object o)

若是此 collection 包含指定的元素,則返回 true。

boolean

isEmpty()

若是此 collection 不包含元素,則返回 true。

boolean

remove(Object o)

今後 collection 中移除指定元素的單個實例。

int

size()

返回此 collection 中的元素數。

boolean

equals(Object o)

比較此 collection 與指定對象是否相等。

Object[]

toArray()

返回包含此 collection 中全部元素的數組。

Iterator<E>

iterator()

返回在此 collection 的元素上的迭代器 (接口)。

Ps:1.傳入均爲形參,不須類型修飾。2.接口不可實例化。方法所有交由實現類實現。

class Arrays { // 除特殊代表,爲 Collection接口全部實現類所的方法

    ArrayList<String> list = new ArrayList<String>();

 

    void OwMethod() {

    list.add("且聽風吟_z");

    list.add("山多拉之燈");

    list.add(0, "Jake"); // 使用下標肯定添加位置

 

    System.out.println(list.get(1)); // list 特有

    System.out.println("下標爲:" + list.indexOf("Jake")); // list 特有

    System.out.println(list.set(0, "Captain")); // 替換元素, list 特有

    System.out.println("判斷包含元素:" + list.contains("Captain"));

 

    System.out.println("該集合有元素數:" + list.size());

    System.out.println("移除元素:" + list.remove("山多拉之燈"));

 

    System.out.println("字符串型式返回元素:" + list.toString());

    System.out.println("這是什麼鬼:" + list.toArray() + "\n");

 

    list.clear(); // 沒有返回值

    System.out.println("\n判斷是否爲空:" + list.isEmpty());

    }

}

Ps:注意元素時對象時的區別

b)     List 接口特有方法(ArraysList、LintkedList 實現接口)

<E>

get(int index)

返回列表中指定位置的元素。

<E>

set(int index, E element)

用指定元素替換列表中指定位置的元素(可選操做)。

c)     LinkedList 類特有方法

<E>

getFirst()

返回此列表的第一個元素。

<E>

getLast()

返回此列表的最後一個元素。

<E>

removeFirst()

移除並返回此列表的第一個元素。

 

class Link { // LinkedList 方法舉例

 

    LinkedList<String> list2 = new LinkedList<String>();

 

    void OwMethod() {

    list2.add("No.1");

    list2.addFirst("我是第一個!");

    list2.add("No.2");

 

    System.out.println("LinkedList 返回元素:" + list2.getFirst());

    list2.removeFirst();

    System.out.println("LinkedList 返回元素:" + list2.toString());

    }

}

Link補充:1. 刪除元素後,index後面的元素會自動向前補齊

2.索引若沒有元素,返回-1

d)     Set接口(HashSet 實現接口)

class Set { // HashSet 方法舉例

    HashSet<String> list6 = new HashSet<String>();

 

    void OwMethod() {

    list6.add("cat");

    list6.add("dog");

    System.out.println(list6.getClass());

    }

}

e)     Map接口 <K,V> (HashMap 實現接口)

返回類型

方法

解釋

boolean

containsKey(Object key)

確保此 collection 包含指定的元素。

<V>

get(Object key)

返回指定鍵所映射的值。

<V>

put(K key, V value)

將指定的值與此映射中的指定鍵關聯。

Collection<V>

values()

返回此映射中包含的值的 Collection集合。

Set<K>

keySet()

返回此映射中所包含的鍵的 Set集合。

 

class Map {

    HashMap<Integer, String> list7 = new HashMap<Integer, String>();

                                  // Map要得是對象,不能放int

    void OwMethod() {

 

    list7.put(1, "car");   // key 不能夠重複

    list7.put(2, "truck"); // Value 的值能夠是普通數據也能夠是對象

    list7.put(3, "bus");

    System.out.println("是否包含key = 1:" + list7.containsKey(1));

    System.out.println("key所對應的值:" + list7.get(1));

    System.out.println("包含Value的全部元素:" + list7.values());

    System.out.println("包含Key的全部元素:" + list7.keySet());

 

    System.out.println("HashMap返回元素:" + list7.toString() + "\n");

    }

}

2.     Iterator 迭代器

boolean

hasNext()

若是仍有元素能夠迭代,則返回 true。

Set<K>

next()

返回迭代的下一個元素。

void

remove()

移除迭代器返回的最後一個元素。

補充:遍歷集合元素的幾種方法

    Collections.sort(list);  // Ps:不是必須的

    Iterator<String> iter = list.iterator(); //1.調用迭代器,遍歷集合元素

    while (iter.hasNext()) {

        String name = iter.next();

        System.out.println(name);

    }

 

    for (String str : list) { // 2.使用加強for循環,遍歷集合元素

        System.out.println(str);

    }

       // 3.轉換成字符串,遍歷集合元素

    System.out.println("HashMap返回元素:" + list.toString() + "\n");

3.     Collections包裝類

       Java.util.Collections 是一個包裝類。它包含有各類有關集合操做的靜態多態方法。此類不能實例化,用於對集合中元素進行排序、搜索以及線程安全等各類操做。

Void

sort(List<T> list) 

根據天然順序 對指定列表按升序進行排序。

<T>

Max

根據天然順序,返回給定 collection 的最大元素。

<T>

Min

根據天然順序,返回給定 collection 的最小元素。

<T>

Max (Comparator)

重寫比較器,返回給定 collection 的最大元素。

<T>

Fill(list,obj)

使用指定元素替換指定列表中的全部元素。

<T>

binarySearch

使用二分搜索法搜索指定列表,以得到指定對象。

注:<T>的正式名稱爲類型參數,也可通俗的稱爲佔位符,符號讀做of  T

    Collections.sort(list);

    Iterator<Student> it = list.iterator();

    while (it.hasNext()) {

        Student stu = (Student) it.next();

        System.out.println(stu.getNumber());

    }

 

    int index = Collections.binarySearch(list, student1);

    System.out.println("student1的下標是:" + index);

 

    Student stu1 = Collections.max(list);

    System.out.println("最大值的下標是:" + stu1.getNumber());

 

    // Collections.fill(list, "我被替換了"); // 替換的是什麼東西??

 

a)     重寫比較器

接口:public interface Comparable<T>

       此接口強行對實現它的每一個類的對象進行總體排序。這種排序被稱爲類的天然排序,類的 compareTo 方法被稱爲它的天然比較方法。

       實現此接口的對象列表(和數組)能夠經過 Collections.sort(和 Arrays.sort

    public int compareTo(Object obj) {

        Student student = (Student) obj;

        if (this.number == student.number) { // 用對象仍是get均可以

            return 0;

        } else if (this.number > student.getNumber()) {

            return 1;

        } else {

        return -1;

        }

    }

4.     補充幾點

a)      注意API中參數是對象仍是普通數據類型。

b)     集合中的元素能夠是普通數據也能夠是對象。

c)      泛型執行定義了類型,避免了裝箱和拆箱操做,性能有很大提升了。詳見 高級特性à包裝類à裝箱/拆箱。

5.     泛型

       泛型,即「參數化類型」。一提到參數,最熟悉的就是定義方法時有形參,而後調用此方法時傳遞實參。那麼參數化類型怎麼理解呢?顧名思義,就是將類型由原來的具體的類型參數化,相似於方法中的變量參數,此時類型也定義成參數形式(能夠稱之爲類型形參),而後在使用/調用時傳入具體的類型(類型實參)。

爲何使用泛型? 先來看使用非泛型集合的兩個問題:性能問題和類型安全問題。

性能問題:無論選擇哪一個類型來保存,都不能避免使用非泛型容器帶來的裝箱問題,因此提出了泛型。

類型安全問題:在泛型以前,要解決類型安全問題的惟一方法是手工建立自定義(強類型的)集合類。

a)     泛型類

b)     泛型方法

c)     泛型接口

2、      實用類

API(Application Programming Interface)應用程序編程接口,它是運行庫的集合,預先定義了一些藉口和類。API 提供以下經常使用的包:

  • Java.lang:java應用最廣發的包,自動導入,提供了包裝類、Math類、String類等java的基礎類和接口。還提供了關於系統管理操做的類。
  • Java.util:包含了系統輔助類,特別是集合類。
  • Java.io:包含了輸入輸出類,用於文件操做。
  • Java.net:包含了網絡相關的類,如Socket、ServerSocker等
  • Java.sql:包含了與數據庫相關的類,如Connection、Statement等

1.     枚舉

public enum Week {

    MON, TUE, WED, THU, FRI, SAT, SUN;

}

// 調用 Week. MON

public enum FORMAT {

    YYYY_MM_DD_FORMAT("yyyy-MM-dd"), // 爲枚舉元素賦值先定義元素,再定義屬性

    DD_MM_YYYY_FORMAT("dd-mm-yyyy");

 

    private String stringValue;

 

    private FORMAT(String stringValue) {

    this.stringValue = stringValue;

    }

    public String getStringValue() {

    return stringValue;

    }

}   // 調用 FORMAT.DD_MM_YYYY_FORMAT.getStringValue()

2.     包裝類

基本數據類型

包裝類

包裝類

包裝類

byte

Byte

Number

Object

short

Short

int

Integer

long

Long

float

Float

double

Double

char

Character

 

boolean

Boolean

 

a)     拆箱與裝箱

大多集合可以處理任何類型的數據,由於這些集合定義的處理對象使用了Object類型。當集合處理的數據是JAVA中的基本類型時,好比int、float、double類型,這些類型在JAVA中屬於值類型,而這些數據進入集合中時,集合可以處理的是Object這樣的引用類型,因此在值類型的數據進入集合的時候,須要將值類型包裝成引用類型,這個過程就是裝箱的過程,從集合中取出數據時,取出的是引用類型,一樣須要把引用類型還原爲值類型,這個過程就是拆箱的過程。

  • 泛型執行定義了類型,避免了裝箱和拆箱操做,性能有很大提升了。
  • JDK1.5後,容許基本數據類型和包裝類型進行混合數學運算。
  • 包裝類並非用來取代基本數據類型的,在基本數據類型須要用對象表示時使用。

b)     基本數據類型轉換成包裝型

        Integer num1 = new Integer(123); // 手動裝箱方式,構造方法

Integer num2 = new Integer("123"); // 除Character類外的基本類型

Character num3 = new Character('a');

Integer num4 = Integer.valueOf(123);

Integer num5 = 1; // 自動裝箱

c)     包裝型轉換成基本數據類型

int num1_1 = num1.intValue(); // 手動拆箱方式

int num5_1 = num5; // 自動拆箱

d)     toString()和parseInt()

  • toString():以字符串形式返回包裝對象表示的基本類型(基本類型->字符串)
  • parseXXX():把字符串轉換爲基本數據類型(Character除外)(字符串->基本類型)

String sex=Character.toString('男');  // 基本類型->字符串

int num=Integer.parseInt("36"); // 字符串->基本類型  

//可用於校驗字符是否合法

sex='男'+"";  // 合併轉換字符串的一種方式

3.     Math類

    //獲取隨機數的兩種random()方法:

    int show1 = (int) (Math.random() * 5.0D) + 1;

    int show2 = (int) (Math.random() * 10.0D) % 5 + 1;

System.out.println(Math.max(show1, show2));

    System.out.println(Math.abs(-10)); // 絕對值運算

System.out.println(Math.E + "\n" + Math.PI); // 兩個常量

//Ps:random()返回一個大於等於0小於1的隨機數。

4.     String類

在Java中,字符串被做爲String類型的對象來處理。String類位於java.lang包中。字符串是一個字符序列,事實上也是一個字符數組。可用下標索引。

    String s1 = "-Java-";

    String s1_1 = s1.toLowerCase(); // 轉爲小寫

    String s1_2 = s1.toUpperCase(); // 轉爲大寫

 

    String s2 = "渺千山暮雪,";

    String s3 = "萬里層雲,";

    String s4 = "隻影向誰去?";

 

    String s5 = s2.concat(s3.concat(s4)); // 鏈接字符串

    String[] s6 = s5.split("。|,|?"); // 字符串拆分,用數組接收

    String s7 = s5.substring(1, 5); // 提取下標區間字段

 

    System.out.println(s1.equals(s1_2)); // 比較字符串,詳見運算符章節

    System.out.println(s1_1.equalsIgnoreCase(s1_2));

    // 比較字符串,忽略大小寫

    System.out.println(s5);

    for (String temp : s6) {

        System.out.println(temp);

    }

    System.out.println(s7); // indexOf()查詢若不存在返回index = -1

    System.out.println(s7.length()); //字符串長度

    System.out.println("第一次出現逗號位置的下標:" + s5.indexOf(","));

    System.out.println("最後出現逗號位置的下標:" + s5.lastIndexOf(","));

5.     StringBufffer類和StringBulider類

    StringBuffer s1 = new StringBuffer("仰天大笑出門去");

    StringBuffer s2 = s1.append("無人知是荔枝來!");// 效率比concat()高

    StringBuffer s3 = s2.insert(7, ",");

    // 返回StringBuffer,不能用String接收。

    int s4 = s3.hashCode();

    //StringBuffer 好多方法能夠用

    System.out.println(s3);

System.out.println(s4);

註釋:StringBufffer類和StringBulider類處理字符串的方法基本一致。

a)      補充幾點:

  • String是不可變對象。每次對String類型改變實際上等同與生成了一個String對象。對常常改變內容的字符串最好不用String類型。String字符串用「+「鏈接其實是經過創建一個StringBuffer對象,調用appent()方法,而後再轉換成String。
  • StringBuffer改變是改變的對象的引用,效率比String要高。
  • StringBulider是單線程的,不提供同步,理論上效率更高。

6.     日期時間類

    Date date = new Date(); // 建立日期對象

    SimpleDateFormat formater // HH表示24時制

                 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    System.out.println("當前時間爲:" + formater.format(date));

 

    Calendar t = Calendar.getInstance();

    // 抽象類,獲得子類對象

    System.out.println("今天是" + t.get(Calendar.YEAR) + "年"

       + (t.get(Calendar.MONTH) + 1) + "月"

       + t.get(Calendar.DAY_OF_MONTH) + "日");

    // Calendar.DAY_OF_WEEK 中 Sunday是 1

    System.out.println("今天是星期"

        + (t.get(Calendar.DAY_OF_WEEK) - 1));

    }

7.     Random類

    Random rand = new Random(47);

    int show1 = rand.nextInt(10); //產生一個大於等於0,小於10的隨機數

    System.out.println(show1);

        //Math.random()方法底層是使用Random類實現的

3、        輸入/輸出、序列化和反射

1.     File類的操做

    @SuppressWarnings("static-access")

    public static void main(String[] args) throws IOException {

    SimpleDateFormat formater

                    = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

 

    File file1 = new File("I:/myDoc");

    // 建立新 File 實例,建立的是引用

    file1.mkdir();

    // 建立文件夾   file.mkdirs()

    file1.createTempFile("temp", ".txt", file1);

    // 建立臨時文件

    System.out.println("是目錄:" + file1.isDirectory());

 

    File file2 = new File("I:/myDoc/temp.txt");

    // 但是文件,也但是目錄

    file2.createNewFile();

    //建立文件

    System.out.println("是文件:" + file2.isFile());

 

    System.out.println("文件是否存在:" + file2.exists());

    System.out.println("名稱:" + file2.getName());

    System.out.println("相對路徑: " + file2.getPath());

    System.out.println("絕對路徑: " + file2.getAbsolutePath());

    System.out.println("文件大小:" + file2.length() + " 字節");

    System.out.println("最後修改日期: " +                                                       formater.format(file2.lastModified()));

}

System.out.println("文件是否刪除:" + file2.delete());

2.     Java的流

流,是指一連串流動的字符,是以先進先出的方式發送和接收數據的通道。流分爲輸入和輸出流。輸入/輸出時相對於內存來講的(往裏讀,往外寫)。Java的輸出流主要有OutputStream和White做爲抽象基類,而輸入流主要由InputStream和Reader做爲抽象基類。

字符流處理的單元爲2個字節的Unicode字符,分別操做字符、字符數組或字符串,而字節流處理單元爲1個字節,操做字節和字節數組。因此字符流是由Java虛擬機將字節轉化爲2個字節的Unicode字符爲單位的字符而成的,因此它對多國語言支持性比較好。

若是是音頻文件、圖片、歌曲,就用字節流好點,若是是關係到中文(文本)的,用字符流好點。

    全部文件的儲存是都是字節(byte)的儲存,在磁盤上保留的並非文件的字符而是先把字符編碼成字節,再儲存這些字節到磁盤。在讀取文件(特別是文本文件)時,也是一個字節一個字節地讀取以造成字節序列。

字節流可用於任何類型的對象,包括二進制對象,而字符流只能處理字符或者字符串;字節流提供了處理任何類型的IO操做的功能,但它不能直接處理Unicode字符,而字符流就能夠。

字節流在操做的時候是直接與文件自己關聯,不使用緩衝區,字節直接存到文件中;字符流在操做的時候是經過緩衝區與文件操做,字符到緩衝區而後再到文件中,因此字符流中存在一個flush()方法來刷新緩衝區。

3.     讀寫文本文檔 

//******** 問題:下列步驟數據存儲和轉換的過程是怎麼樣的? 編碼:UTF-8 *******

// 1. 把一個字符串 "蘇A" 輸入緩衝區 (33487)10000010 11001111 (65)01000001 UTF-16

// 1. 在緩衝區加高位轉換成UTF=8 11101000/10001011/10001111/01000001

// 2. 轉換成byte[] //用長度爲4的字節數組接受 Byte1 = 11101000 Byte2 = ...

// 3 .而後存入文本 // 把四個字節數組存入文本(閱讀文本時,解碼器解碼)

// 4. 而後從文本讀取 //把文檔內容以字節(符)型式讀入內存,並轉換成char

// 注:蘇A == (\u82cf--16進製表達)

            ((232) 11101000 (139) 10001011 (143) 10001111) (65)01000001

// 若是不知道編碼方式,可能一樣的二進制數,解碼方式有誤,致使解碼失敗。

// IO操做的是序號,經過字庫表,對應顯示正確的字符。

public class Keep_Stream_Test {

 

    public static void main(String[] args) throws IOException {

 

    int date, temp;

    String line;

    String str = "蘇A"; //UTF-8 漢字一個字符約三個字節

    char a = 'C'; // 一個整型表明一個字符,故能夠互相轉換

    byte[] words = str.getBytes(); // 把字符串內容寫進字節數組

    System.out.println(System.getProperty("file.encoding"));

    // 得到本地平臺的字符編碼類型

    /**

     * 字節流寫入數據

     * */

    FileOutputStream fos1 = new FileOutputStream("I:/text1.txt");

    fos1.write(552); // 讀寫的是序號 // 往裏讀,往外寫 // 非正確演示

    fos1.write(words, 0, words.length);// 把字節數組存儲的內容寫進流

    /**

     * 字符流寫入數據

     * */

    FileWriter fw = new FileWriter("I:/text1.txt", true);//不覆蓋原文件

    BufferedWriter bw = new BufferedWriter(fw); // 裝飾者模式

    bw.write("-南京");

    bw.write(')');

    bw.flush(); // 往外寫時才用

    /**

     * 字節流讀取數據

     * */

    FileInputStream fis1 = new FileInputStream("I:/text1.txt");

    BufferedInputStream bis1 = new BufferedInputStream(fis1);

    System.out.println("文件大小:" + bis1.available() + "字節\n");

    while ((date = fis1.read()) != -1) { // 把文本內容以字節型式讀入內存

        System.out.print(date);

        System.out.print((char) date);

        System.out.println("\t" + Integer.toBinaryString(date));

    }

    // 此處對應關係與編碼方式有關,多字節解碼方式有誤

    // 沒有緩衝區,讀一個字節,轉一個。so若是漢字是單字節就不會出錯鳥~

    System.out.println('\n');

    /**

     * 字符流讀取數據

     * */

    FileReader fr1 = new FileReader("I:/text1.txt");

    BufferedReader br1 = new BufferedReader(fr1);

    while ((date = br1.read()) != -1) { // 把文檔內容以字符型式讀入內存

        System.out.print(date);

        System.out.print((char) date);

        System.out.println("\t" + Integer.toBinaryString(date));

    }

    while ((line = br1.readLine()) != null) {

        // 把文檔內容以字符型式(每次一行)讀入內存,返回字符串。這一段讀不出流           只可用一次。

        System.out.print(line);

        // 因爲字符流有緩衝區,因此2個字符讀(Unicode)與一行行讀均可以,最終按            編碼方式處理。

    }

    /**

     * 字符流讀取數據 InputStreamReader 是字節流通向字符流的橋樑

     * */

    InputStreamReader isr = new InputStreamReader(fis1, "UTF-8");

    // 轉換流

    BufferedReader br2 = new BufferedReader(isr);// 緩衝流

    while ((temp = br2.read()) != -1) {

        System.out.print((char) temp); // 流使用一次就不能再用了??

    }

    System.out.println('\u82cf');// 十六進制表示一個字符

    System.out.println((byte) a);

    }

}

a)     節點流與處理流

  • IO中的使用到了一個設計模式:裝飾設計模式。寫一個類(包裝類)對被包裝對象進行包裝,對一組類進行功能的加強。
  • 節點流:節點流從一個特定的數據源讀寫數據。即節點流是直接操做文件,網絡等的流,他們直接從文件中讀取或往文件中寫入字節流。對文件操做的字符流有FileReader/ FileWriter,字節流有FileInputStream/FileOutputStream。
  • 處理流:「鏈接」在已存在的流(節點流或處理流)之上經過對數據的處理爲程序提供更爲強大的讀寫功能。過濾流是使用一個已經存在的輸入流或輸出流鏈接建立的,過濾流就是對節點流進行一系列的包裝。

u  緩衝流:緩衝流要「套接」在相應的節點流之上,對讀寫的數據提供了緩衝的功能。

²  字節緩衝流有BufferedInputStream/ BufferedOutputStream,字符緩衝流有BufferedReader/BufferedWriter,字符緩衝流分別提供了讀取和寫入一行的方法ReadLine和NewLine方法。使用字符緩衝流的時候,必定先flush,再close。

u  轉換流:用於字節數據到字符數據之間的轉換。

²  字符流InputStreamReader/OutputStreamWriter。其中,InputStreamReader須要與InputStream「套接」,OutputStreamWriter要與OutputStream「套接」。

u  數據流:提供了讀寫Java中的基本數據類型的功能。

²  DataInputStream和DataOutputStream分別繼承自InputStream和OutputStream,須「套接」在InputStream和OutputStream類型的節點流上。

u  對象流:用於直接將對象寫入寫出。

²  對象流類有ObjectInputStream和ObjectOutputStream,自己這兩個方法沒什麼,可是其要寫出的對象有要求,該對象必須實現Serializable接口,來聲明其是能夠序列化的。不然,不能用對象流讀寫。

u  還有一個關鍵字比較重要,transient,因爲修飾實現了Serializable接口的類內的屬性,被該修飾符修飾的屬性,在以對象流的方式輸出的時候,該字段會被忽略。

b)     補充幾點:

①       FileInputStream和FileReader的區別

兩個類的構造方法的形式和參數都是相同的,參數爲File對象或表示路徑的String。

FileInputStream以字節流方式讀取,FileReader把文件轉換爲字符流讀入。

②       BufferedWriter和PrintWriter的區別

PrintWriter提供的print/println/printf等方法方便使用,並封裝了字節流與字符流之間的轉換。BufferedWriter提供緩衝。詳見TCP編程章節例程。

③       構造方法的形式和參數的區別

File流以文件做爲參數,處理流以節點流或其子類做爲參數。

  • Ø  參考資料:

       Java輸入、輸入、IO流 類層次關係梳理  http://www.cnblogs.com/LittleHann/p/3678685.html 

4.     讀寫二進制文檔

    /**

     * 二進制文件讀取操做

     * */

    FileInputStream fis3 = new FileInputStream("I:/text1.txt");

    DataInputStream dis1 = new DataInputStream(fis3);

    /**

     * 二進制文件寫入操做

     * */

    FileOutputStream fos2 = new FileOutputStream("I:/text2.txt");

    DataOutputStream dos1 = new DataOutputStream(fos2);

    int temp2;

    while ((temp2 = dis1.read()) != -1) { // 讀取文件並寫入文件

        dos1.write(temp2);

    }

    dos1.writeUTF("Hello"); // 將一個字符串寫入文件

    dos1.flush();

5.     重定向標準 I/O

Java的標準輸入/輸出分別經過System.in和System.out來表明,在默認的狀況下分別表明鍵盤和顯示器,當程序經過System.in來得到輸入時,其實是經過鍵盤得到輸入。當程序經過System.out執行輸出時,程序老是輸出到屏幕。

       /**

      * System.out 重定向向文件輸出

       * */

       PrintStream ps = new PrintStream(new FileOutputStream("work"));

       System.setOut(ps);

       System.out.println("Hello World!");

       /**

        * System.in 重定向從文件輸入

        * */

       FileInputStream fis = new FileInputStream("work");

       System.setIn(fis);

   

       Scanner sc = new Scanner(System.in);

       while (sc.hasNextLine()) {

           System.out.println(sc.nextLine());

       }

6.     序列化與反序列化

序列化是將對象的狀態寫入到特定的流中的過程,反序列化則是從特定的流中獲取數據從新構建對象的過程。

    ObjectOutputStream oos = new ObjectOutputStream(new                                             FileOutputStream("c:\\myDoc\\stu.txt"));

    Student stu = new Student("安娜", 30, "女");

    // 對象序列化

    oos.writeObject(stu);

 

    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(

                                                   "c:\\myDoc\\stu.txt"));

    // 對象反序列化

    Student stu1 = (Student) ois.readObject();

    System.out.println("姓名爲:" + stu1.getName());

    System.out.println("年齡爲:" + stu1.getAge());

    System.out.println("性別爲:" + stu1.getGender());

Ps:class Student implements java.io.Serializable

補充:靜態數據不能被序列化,由於靜態數據不在堆內存中,是存儲在靜態方法區中。用transient 關鍵字修飾非靜態數據也不會被序列化。

7.     反射機制

其實就是動態加載一個指定的類,並獲取該類中的全部的內容。並且將字節碼文件封裝成對象,並將字節碼文件中的內容都封裝成對象,這樣便於操做這些成員。簡單說:反射技術能夠對一個類進行解剖。反射技術大大的加強了程序的擴展性。

a)      反射的基本步驟:

  • 得到Class對象,就是獲取到指定的名稱的字節碼文件對象。
  • 實例化對象,得到類的屬性、方法或構造函數。
  • 訪問屬性、調用方法、調用構造函數建立對象。

b)     獲取這個Class對象的三種方式

 

c)      建立對象的兩種方式

 

參考資料:

 

8.     補充幾點

a)      字符集和字符編碼

咱們在計算機屏幕上看到的是實體化的文字,而在計算機存儲介質中存放的實際是二進制的比特流。那麼在這二者之間的轉換規則就須要一個統一的標準。

字符是各類文字和符號的總稱,包括各國家文字、標點符號、圖形符號、數字等。均佔一個字符,但字節長度因爲編碼方式的不一樣而不一樣。

字符集(Charset):是字符的集合。常見字符集有:ASCII字符集、ISO-8859-1字符集(兼容ASCII) 、GB2312字符集(兼容ASCII) 、GBK字符集(兼容GB2312)、BIG5字符集、GB18030字符集(兼容GBK)、Unicode(兼容ISO-8859-1)字符集等。

字符不必定適合做傳輸、儲存等處理,有時須經編碼(encode)後才能應用。如Unicode(UTF-八、UTF-1六、UTF-32)、GBK等方式編碼。

對於一個字符集來講要正確編碼轉碼一個字符須要三個關鍵元素:字庫表(character repertoire)、編碼值(coded character set)、字符編碼(character encoding form)。其中字庫表是一個至關於全部可讀或者可顯示字符的數據庫,字庫表決定了整個字符集可以展示表示的全部字符的範圍。用一個編碼值(數值代碼)來對應字庫中的每個字符。字符編碼,將編碼值(數值代碼)以必定編碼方式轉化成二進制數,以便與進行傳輸、儲存等處理。過程:字符à編碼值à二進制值。

 

蘇A 的 存 儲 形 式 爲 :

ASCII 碼: (33487) 10000010 11001111      (65) 01000001

UTF-8: (\u82cf)( (232) 11101000 (139) 10001011      (143) 10001111)      (65) 01000001

  • Ø  ASCII碼:一個英文字母(不分大小寫)佔一個字節的空間,一箇中文漢字佔兩個字節的空間。一個二進制數字序列,在計算機中做爲一個數字單元,通常爲8位二進制數,換算爲十進制。最小值0,最大值255。如一個ASCII碼就是一個字節。
  • Ø  Unicode編碼:一個英文等於兩個字節,一箇中文(含繁體)等於兩個字節。
  • Ø  UTF-8編碼:一個英文字符等於一個字節,一箇中文(含繁體)≈三個字節。

符號:英文標點佔一個字節,全角兩個字節。中文標點佔兩個字節,全角四個字節。

  • Ø  Java中的字符流處理的最基本的單元是Unicode碼元。因爲字符流在輸出前其實是要完成Unicode碼元序列到相應編碼方式的字節序列的轉換,因此它會使用內存緩衝區來存放轉換後獲得的字節序列,等待都轉換完畢再一同寫入磁盤文件中

參考文章:十分鐘搞清字符集和字符編碼字符集和字符編碼(Charset & Encoding

字符編碼詳解——完全理解掌握編碼知識,「亂碼」不復存在

b)     文本文件與二進制文件的區別

全部的文件在內存和磁盤中都是二進制格式的,因此文本文件與二進制文件的區別並非物理上的,而是邏輯上的。這二者只是在編碼層次上有差別。

文本文件是基於字符編碼的文件,常見的編碼有ASCII(雙字節字符集)、Unicode(可變字節字符集)編碼等。二進制文件是基於值編碼的文件,二進制讀取只可正對二進制文件。

用ASCII方式處理文件,一個字節(8 Bite)放一個ASCII字符,於是便於對字符進行逐個處理,也便於輸出字符,但通常佔儲空間較多,並且要花費較多的轉換時間。二進制文件是把內存中的數據按其在內存中的存儲形式原樣輸出到磁盤上存放,用二進制形式輸出數值,能夠節省外存空間和轉換時間。

文本文件的讀取須要按照相應的編碼方式進行解碼。

5678 的 存 儲 形 式 爲 :

ASCII 碼: 00110101   00110110   00110111   00111000 (四個字節)

二進制:   00010110   00101110 (兩個字節)

註釋:ASCII碼是8 Bite的編碼,Unicode碼元通常佔16 Bite

c)      數據結構相關知識

待補充~

 

4、        註解和多線程

1.     註解

       註解一種標記

       Annotation  //註解

       @Deprecated

       @SuppressWarnings("deprecation") 消除警告

       @Override 重寫 

       自定義註解

       好比A註解

       public @interface A {

       }

       元註解

              @Retention

              @Target

待補充~

2.     多線程

進程:正在進行中的程序。其實進程就是一個應用程序運行時的內存分配空間。

線程:其實就是進程中一個程序執行控制單元,一條執行路徑。進程負責的是應用程序的空間的標示。線程負責的是應用程序的執行順序。

a)      建立線程

public class Thread_Demo {

 

    public static void main(String[] args) {

    Demo1 d1 = new Demo1(); // Runnable實現類,只有run()方法

    Thread t = new Thread(d1); // Thread對象調用start()方法

    t.start();

   

    Demo2 d2 = new Demo2();

    d2.start(); //Thread對象調用start()方法

    }

}

 

class Demo1 implements Runnable { // 實現Runnable接口方式實現多線程

 

    public void run() {

    System.out.println("Runnable");

    }

}

 

class Demo2 extends Thread { // 繼承Thread類實現多線程

    public void run() {

    System.out.println("Thread");

    }

      

b)     線程的生命週期

  • 新建狀態(New):新建立了一個線程對象。
  • 就緒狀態(Runnable):線程對象建立後,其餘線程調用了該對象的start()方法。該狀態的線程位於可運行線程池中,變得可運行,等待獲取CPU的使用權。

運行狀態(Running):就緒狀態的線程獲取了CPU,執行程序代碼。

  • 阻塞狀態(Blocked):阻塞狀態是線程由於某種緣由放棄CPU使用權,暫時中止運行。直到線程進入就緒狀態,纔有機會轉到運行狀態。阻塞的狀況分三種:

u  等待阻塞:運行的線程執行wait()方法,JVM會把該線程放入等待池中。

u  同步阻塞:運行的線程在獲取對象的同步鎖時,若該同步鎖被別的線程佔用,則JVM會把該線程放入鎖池中。

u  其餘阻塞:運行的線程執行sleep()或join()方法,或者發出了I/O請求時,JVM會把該線程置爲阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程從新轉入就緒狀態。

  • 死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命週期。

c)      多線程安全問題 

當多條語句在操做同一個線程共享數據時,一個線程對多條語句只執行了一部分,還沒執行完,另外一個線程參與進來執行,致使共享數據的錯誤。

解決辦法:對多條操做共享數據的語句,只能讓一個線程都執行完,在執行過程當中,其餘線程不執行。

同步代碼塊:

public class ThreadDemo {

    public static void main(String[] args) {

    Ticket t = new Ticket();

    Thread t1 = new Thread(t, "窗口一");

    Thread t2 = new Thread(t, "窗口二");

    Thread t3 = new Thread(t, "窗口三");

    Thread t4 = new Thread(t, "窗口四");

    t1.start();

    t2.start();

    t3.start();

    t4.start();

    }

}

 

class Ticket implements Runnable {

    private int ticket = 100;

 

    public void run() {

    while (true) {

        synchronized (new Object()) {

// synchronized關鍵字,用來修飾方法或代碼塊的時,保證同時最多隻有一個線程執行    該段代碼。

        if (ticket <= 0)

            break;

        System.out.println(Thread.currentThread().getName()

            + "---賣出"+ ticket--);

        }

    }

    }

}

 

同步函數:

public class ThreadDemo {

    public static void main(String[] args) {

    Ticket t = new Ticket();

    Thread t1 = new Thread(t, "窗口一");

    Thread t2 = new Thread(t, "窗口二");

    Thread t3 = new Thread(t, "窗口三");

    Thread t4 = new Thread(t, "窗口四");

    t1.start();

    t2.start();

    t3.start();

    t4.start();

    }

}

 

class Ticket implements Runnable {

    private int ticket = 100;

 

public synchronized void saleTicket() {

    if (ticket > 0)

        System.out.println(Thread.currentThread().getName() + "賣出了"

            + ticket--);

    }

 

    public void run() {

    while (true) {

        saleTicket();

    }

    }

}

 

等待喚醒機制:

 

生產消費機制:

 

參考資料:

 

5、      網絡編程

網絡編程的目的就是指直接或間接地經過網絡協議與其餘計算機進行通信。網絡編程中有兩個主要的問題,一個是如何準確的定位網絡上一臺或多臺主機,另外一個就是找到主機後如何可靠高效的進行數據傳輸。在TCP/IP協議中IP層主要負責網絡主機的定位,數據傳輸的路由,由IP地址能夠惟一地肯定Internet上的一臺主機。而TCP層則提供面向應用的可靠的或非可靠的數據傳輸機制,這是網絡編程的主要對象,通常不須要關心IP層是如何處理數據的。

目前較爲流行的網絡編程模型是客戶機/服務器(C/S)結構。

1.     網絡基礎知識

a)      TCP/IP協議

是目前世界上應用最爲普遍的協議,是以TCP和IP爲基礎的不一樣層次上多個協議的集合,也成TCP/IP協議族、或TCP/IP協議棧

  • TCP:Transmission Control Protocol 傳輸控制協議
  • IP:Internet Protocol 互聯網協議
  • 應用層:HTTP、FTP、SMTP、Telnet等
  • 傳輸層:TCP/IP
  • 網絡層:
  • 數據鏈路層:
  • 物理層:網線、雙絞線、網卡等

b)     TCP/IP五層模型

c)      IP地址

IP網絡中每臺主機都必須有一個惟一的IP地址,IP地址是一個邏輯地址。

d)     協議

爲進行網絡中的數據交換(通訊)而創建的規則、標準或約定。(=語義+語法+規則)。

  不一樣層具備各自不一樣的協議。

e)     端口

IP地址用來標識網絡上的計算機,而端口號用來指明該計算機上的應用程序。

f)      數據封裝

一臺計算機要發送數據到另外一臺計算機,數據首先必須打包,打包的過程稱爲封裝。

  封裝就是在數據前面加上特定的協議頭部。

g)     Socket套接字

網絡上具備惟一標識的IP地址和端口組合在一塊兒才能構成惟一能識別的標識符套接字。

  • Socket原理機制:

u  通訊的兩端都有Socket。

u  網絡通訊其實就是Socket間的通訊。

u  數據在兩個Socket間經過IO傳輸。

h)     Java中的網絡支持

針對網絡通訊的不一樣層次,Java提供了不一樣的API,其提供的網絡功能有四大類:

  • InetAddress:用於標識網絡上的硬件資源,主要是IP地址。
  • URL:統一資源定位符,經過URL能夠直接讀取或寫入網絡上的數據。
  • Sockets:使用TCP協議實現的網絡通訊Socket相關的類。
  • Datagram:使用UDP協議,將數據保存在用戶數據報中,經過網絡進行通訊。
  • InetAddress類用於標識網絡上的硬件資源,標識互聯網協議(IP)地址。

2.     InetAddress

       // 使用域名建立對象

        InetAddress inet1 = InetAddress.getByName("www.163.com");

        System.out.println(inet1);

        // 使用IP建立對象

        InetAddress inet2 = InetAddress.getByName("127.0.0.1");

        // 127.0.0.1是一個回送地址,指本地機,通常用來測試使用

        System.out.println(inet2);

        // 得到本機地址對象

        InetAddress inet3 = InetAddress.getLocalHost();

        System.out.println(inet3);

        // 得到對象中存儲的域名

        String host = inet3.getHostName();

        System.out.println("域名:" + host);

        // 得到對象中存儲的IP

        String ip = inet3.getHostAddress();

        System.out.println("IP:" + ip);

3.     URL類

        // 建立一個URL的實例

        URL baidu = new URL("http://www.baidu.com");

        URL url = new URL(baidu, "/index.html?username=tom#test");

        // ?表示參數,#表示錨點

        System.out.println(url.getProtocol());

        // 獲取協議

        System.out.println(url.getHost());

        // 獲取主機

        System.out.println(url.getPort());

        // 若是沒有指定端口號,根據協議不一樣使用默認端口。getPort()方法的返回值爲 -1

        System.out.println(url.getPath());

        // 獲取文件路徑

        System.out.println(url.getFile());

        // 文件名,包括文件路徑+參數

        System.out.println(url.getRef());

        // 相對路徑,就是錨點,即#號後面的內容

        System.out.println(url.getQuery());

        // 查詢字符串,即參數

  • 經過URL對象的openStream()方法能夠獲得指定資源的輸入流,經過流可以讀取或訪問網頁上的資源

       URL url_2 = new URL("http://www.baidu.com");

        InputStream is = (InputStream) url_2.openStream();

        // 經過openStream方法獲取資源的字節輸入流

        InputStreamReader isr = new InputStreamReader(is, "UTF-8");

        // 將字節輸入流轉換爲字符輸入流,若是不指定編碼,中文可能會出現亂碼

        BufferedReader br = new BufferedReader(isr);

        // 爲字符輸入流添加緩衝,提升讀取效率

        String data = br.readLine();// 讀取數據

        while (data != null) {

        System.out.println(data);// 輸出數據

        data = br.readLine();

        }

        br.close();

        isr.close();

        is.close();

 

4.     TCP編程

TCP協議是面向鏈接的、可靠的、有序的、以字節流的方式發送數據,經過三次握手方式創建鏈接,造成傳輸數據的通道,在鏈接中進行大量數據的傳輸,效率會稍低。

a)      Java中基於TCP協議實現網絡通訊的類

  • 客戶端的Socket類
  • 服務器端的ServerSocket類

 

 

 

 

 

 

 

 

 

 

 

b)     Socket通訊的步驟

①     建立ServerSocket和Socket

②     打開鏈接到Socket的輸入/輸出流

③     按照協議對Socket進行讀/寫操做

④     關閉輸入輸出流、關閉Socket

c)      服務器端

①     建立ServerSocket對象,綁定監聽端口

②     經過accept()方法監聽客戶端請求

③     鏈接創建後,經過輸入流讀取客戶端發送的請求信息

④     經過輸出流向客戶端發送鄉音信息

⑤     關閉相關資源

public class DemoTCP_Server {

    public static void main(String[] args) throws IOException {

    /**

     * 基於TCP協議的Socket通訊,實現用戶登陸,服務端

     */

    // 一、建立一個服務器端Socket,即ServerSocket,指定綁定的端口,並監聽此端口

    ServerSocket serverSocket = new ServerSocket(10086);

    // 二、調用accept()方法開始監聽,等待客戶端的鏈接

    Socket socket = serverSocket.accept();

    // 三、getInputStream()方法獲取輸入流,並讀取客戶端信息

    InputStream is = socket.getInputStream(); // 返回InputStream

    InputStreamReader isr = new InputStreamReader(is); // 轉化流處理

    BufferedReader br = new BufferedReader(isr);

    String info = null;

    while ((info = br.readLine()) != null) {

        System.out.println("我是服務器,客戶端說:" + info);

    }

    socket.shutdownInput(); // 關閉輸入流

    // 四、獲取輸出流,響應客戶端的請求

    OutputStream os = socket.getOutputStream();

    PrintWriter pw = new PrintWriter(os);

    pw.write("歡迎您!");

    pw.flush();

 

    // 五、關閉資源,注意順序

    pw.close();

    os.close();

    br.close();

    isr.close();

    is.close();

    socket.close();

    serverSocket.close();

    }

}

 

d)     客戶端

①     建立Socket對象,指明須要鏈接的服務器的地址和端口號

②     鏈接創建後,經過輸出流想服務器端發送請求信息

③     經過輸入流獲取服務器響應的信息

④     關閉響應資源

public class DemoTCP_Clinet { // 客戶端

    public static void main(String[] args) throws IOException {

 

    // 一、建立客戶端Socket,指定服務器地址和端口

    Socket socket = new Socket("localhost", 10086);

    // 二、獲取輸出流,向服務器端發送信息

    OutputStream os = socket.getOutputStream();// 字節輸出流

    PrintWriter pw = new PrintWriter(os);// 將輸出流包裝成打印流

    pw.write("用戶名:admin;密碼:123");

    pw.flush();

    socket.shutdownOutput();

    // 關閉客戶端的輸出流。至關於給流中加入一個結束標記-1

    // 三、獲取輸入流,並接收服務器端的反饋信息

    InputStream is = socket.getInputStream();

    // BufferedReader br = new BufferedReader(new InputStreamReader(is));

    Scanner input = new Scanner(new InputStreamReader(is));

    while (input.hasNextLine()) { //用Scanner接收輸入流,對比服務端方法優劣

        System.out.println("我是客戶端,服務器說:" + input.nextLine());

    }

 

    // 四、關閉資源

    input.close();

    is.close();

    pw.close();

    os.close();

    socket.close();

    }

}

e)     例程小結

①       上例中幾種讀寫方式的對比

PrintWriter做爲一個便捷的字節流與字符流之間的轉換工具,已經封裝了轉換的方法,直接使用它回寫的時候,不用再使用getBytes()轉換成字節流。

如用byte數組接收,將獲得的字節流寫入數組後,得把它轉化爲一個String的對象(用String(數組名,第一個索引,長度))。

如用緩衝流接收時,須要用InputStreamReader轉化。綜合來講,仍是PrintWriter比較方便。

②       Socke的shutdownInput()與close的區別

shutdownInput():關閉Socket的輸入流,程序還能夠經過該Socket的輸出流輸出數據。

客戶端鏈接到服務器後,開始發送數據,發送完成後無須再次發送數據,只須要讀取服務器響應數據便可,當讀取響應完成後,該Socket鏈接也被關閉了。

③       用Scanner接收輸入流,對比服務端方法優劣

Scanner接收InputSteam對象,調用nextLine()方法讀取流文件。

f)      應用多線程實現服務器與多客戶端之間的通訊

①     服務器端建立ServerSocket,循環調用accept()等待客戶端鏈接

②     客戶端建立一個socket並請求和服務器端鏈接

③     服務器端接受客戶端請求,建立socket與該客戶創建專線鏈接

④     創建鏈接的兩個socket在一個單獨的線程上對話

⑤     服務器端繼續等待新的鏈接 

public class DemoThread_Clinet { // 客戶端

    public static void main(String[] args) throws IOException {

    Socket socket = new Socket("localhost",10086);

    socket.close();

    }

}

public class DemoThread_Server extends Thread {// 服務器端

    Socket socket = null;

    public DemoThread_Server(Socket socket) { // 以Sockeet爲參的構造方法

    this.socket = socket;

    }

 

    public void run() {

    }

 

    public static void main(String[] args) throws IOException {

    ServerSocket serverSocket = new ServerSocket(10086);

    Socket socket = null;

    int count = 0;// 記錄客戶端的數量

    while (true) {

        socket = serverSocket.accept();

        // 阻塞狀態,接收客戶端請求,而後往下執行,新增線程

        DemoThread_Server serverThread = new DemoThread_Server(socket);

        serverThread.start();

        count++;

        System.out.println("客戶端鏈接的數量:" + count);

    }

    }

}

 

5.     UDP編程

UDP協議(用戶數據報協議)是無鏈接的、不可靠的、無序的,速度快。進行數據傳輸時,首先將要傳輸的數據定義成數據報(Datagram),大小限制在64k,在數據報中指明數據索要達到的Socket(主機地址和端口號),而後再將數據報發送出去。

a)      Java中基於TCP協議實現網絡通訊的類

  • DatagramPacket類:表示數據報包
  • DatagramSocket類:進行端到端通訊的類

b)     服務器端實現步驟

①     建立DatagramSocket,指定端口號

②     建立DatagramPacket

③     接受客戶端發送的數據信息

④     讀取數據

public class DemoUDP_Server {

    /**

     * 服務器端,實現基於UDP的用戶登陸

     * */

    public static void main(String[] args) throws IOException {

 

    // 一、建立服務器端DatagramSocket,指定端口

    DatagramSocket socket = new DatagramSocket(8888);

    // 二、建立數據報,用於接受客戶端發送的數據

    byte[] data = new byte[1024];

    DatagramPacket packet = new DatagramPacket(data, data.length);

    // 三、接受客戶端發送的數據

    socket.receive(packet);// 此方法在接受數據報以前會一直阻塞

    // 四、讀取數據

    String info = new String(data, 0, data.length);

    System.out.println("我是服務器,客戶端告訴我" + info);

 

    // 一、定義客戶端的地址、端口號、數據

    InetAddress address = packet.getAddress();

    int port = packet.getPort();

    byte[] data2 = "歡迎您!".getBytes();

    // 二、建立數據包,包含響應的數據信息

    DatagramPacket packet2 = new DatagramPacket(data2, data2.length,

        address, port);

    // 三、響應客戶端`

    socket.send(packet2);

    // 四、關閉資源

    socket.close();

    }

}

c)      客戶端實現步驟

①     定義發送信息

②     建立DatagramPacket,包含將要發送的信息

③     建立DatagramSocket

④     發送數據

public class DemoUDP_Clinet { // 客戶端

 

    public static void main(String[] args) throws IOException {

   

    // 一、定義服務器的地址、端口號、數據

    InetAddress address = InetAddress.getByName("localhost");

    int port = 8888;

    byte[] data = "用戶名:admin;密碼:123".getBytes();

    // 二、封包,包含發送的數據信息

    DatagramPacket packet = new DatagramPacket(data, data.length, address,

        port);

    // 三、建立DatagramSocket對象

    DatagramSocket socket = new DatagramSocket();

    // 四、向服務器發包

    socket.send(packet);

 

    // 一、建立數據包,用於接受服務器端響應數據

    byte[] data2 = new byte[1024];

    DatagramPacket packet2 = new DatagramPacket(data2, data2.length);

    // 二、接受服務器響應的數據

    socket.receive(packet2);

    String reply = new String(data2, 0, packet2.getLength());

    System.out.println("我是客戶端,服務器說:" + reply);

    // 四、關閉資源

    socket.close();

    }

}

6.     注意問題

a)      多線程的優先級問題

 

參考資料:

 

 

6、      XML

1.     XML 基礎

2.     XML 註釋

3.     XML 解析

<?xml version = "1.0" encoding="UTF-8"?>

<PhoneInfo>

    <Brand name="華爲">

       <Type name="U8650"></Type>

       <Type name="HW123"></Type>

       <Type name="HW321"></Type>

    </Brand>

    <Brand name="蘋果">

       <Type name="Iphone5"></Type>

       <Type name="Iphone6"></Type>

       <Type name="Iphone6s"></Type>

    </Brand>

</PhoneInfo>

public class ParseXMLDemo { // Document、NoteList、Note、Element 接口

    private Document document;

 

    public static void main(String[] args) throws Exception {

    ParseXMLDemo pd = new ParseXMLDemo();

    pd.getDocument();

    pd.showInfo();

    System.out.println("------------------");

    pd.add();

    pd.delete();

    pd.update();

    pd.showInfo();

    pd.saveXML("E:/JAVA/U1/U2-1/src/chapter06/new.xml");

    }

 

    public void getDocument() throws Exception { // 得到DOM樹

    DocumentBuilderFactory factory =                                                       DocumentBuilderFactory.newInstance();

    DocumentBuilder builder = factory.newDocumentBuilder();

    document =                                                                    builder.parse("E:/JAVA/U1/U2-1/src/chapter06/XMLDemo.xml");

    // 一、建立解析器工廠 二、建立解析器 三、操做xml對象

    }

 

    public void showInfo() {// 獲取手機品牌和屬性

    NodeList brands = document.getElementsByTagName("Brand");

    for (int i = 0; i < brands.getLength(); i++) {

        Node node = brands.item(i);

        Element eleBrand = (Element) node;// 節點強轉元素

        System.out.println(eleBrand.getAttribute("name"));

 

        NodeList types = node.getChildNodes();

        for (int j = 1; j < types.getLength(); j++) {

       Node typeNode = types.item(j);

       if (typeNode.getNodeType() == node.ELEMENT_NODE) {//元素節點

           Element eleType = (Element) typeNode;

           System.out.println("\t" + eleType.getAttribute("name"));

       }

        }

    }

    }

 

    public void saveXML(String path) throws Exception {

    TransformerFactory factory = TransformerFactory.newInstance();

    factory.setAttribute("indent-number", "4");// 設置縮進

    Transformer transformer = factory.newTransformer();

    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");//轉換器

    transformer.setOutputProperty(OutputKeys.INDENT, "yes");//開啓縮進

    // StreamResult result=new StreamResult(new FileOutputStream(path));

    DOMSource source = new DOMSource(document);// 設置源

    StreamResult result = new StreamResult(new OutputStreamWriter(

       new FileOutputStream(path), "UTF-8"));// 設置目標

    transformer.transform(source, result);// 轉換

    }

 

    public void add() throws Exception {// 添加

    Element element1 = document.createElement("Brand");

    element1.setAttribute("name", "三星");

    Element element2 = document.createElement("Type");

    element2.setAttribute("name", "Note3");

    element1.appendChild(element2);

    document.getElementsByTagName("PhoneInfo").item(0)

       .appendChild(element1);

    this.saveXML("E:/JAVA/U1/U2-1/src/chapter06/new.xml");

    }

 

    public void update() throws Exception {// 修改

    NodeList brands = document.getElementsByTagName("Brand");

    for (int i = 0; i < brands.getLength(); i++) {

        Node brand = brands.item(i);

        Element eleBrand = (Element) brand; // 修改的是元素的屬性

        eleBrand.setAttribute("id", i + ""); // i轉爲String

        this.saveXML("E:/JAVA/U1/U2-1/src/chapter06/new.xml");

    }

    }

 

    public void delete() throws Exception {// 刪除

    NodeList brands = document.getElementsByTagName("Brand");

    for (int i = 0; i < brands.getLength(); i++) {

        Node brand = brands.item(i);

        Element eleBrand = (Element) brand;

        if ("華爲".equals(eleBrand.getAttribute("name"))) {

       eleBrand.getParentNode().removeChild(eleBrand);

        }

        this.saveXML("E:/JAVA/U1/U2-1/src/chapter06/new.xml");

    }

    }

}

 

 

 


在內存中分配連續的空間,

遍歷訪問效率高,可是在添加和刪除

非尾部元素時會致使後面的全部元素的移動,

致使須要從新判斷後面元素的下標,

這就形成ArrayList對插入、刪除、等操做性能低下。

相關文章
相關標籤/搜索