Java入門第一季
1.JAVA標識符注意事項:
(1)JAVA標識符可以由字母、數字、下劃線(_)、美元符($)組成,但不能包含@、%、空格等其它特殊字符,不能以數字開頭。
(2)標識符不能是Java關鍵字和保留字(Java預留的關鍵字,以後的升級版本中有可能作爲關鍵字),但可以包含關鍵字和保留字。
(3)標識符是嚴格區分大小寫的。
(4)標識符的命名最好能反映出其作用,做到見名知意。
2.Java中的數據類型
在Java的領域裏,基本數據類型變量存的是數據本身,而引用類型變量存的是數據的空間地址。
3.Java語言中常用的運算符:
算術運算符、賦值運算符、比較運算符、邏輯運算符、條件運算符。
4.使用Arrays類操作Java中的數組:
- 排序
語法:Arrays.sort(數組名);
- 將數組轉換爲字符串
語法:Arrays.toString(數組名);
Java入門第二季
1.類
類是模子,確定對象將會擁有的特徵(屬性)和行爲(方法)。
類的特點:
類是對象的類型
具有相同屬性和方法的一組對象的集合。
2.使用對象的步驟:
- 創建對象:
類名 對象名 = new 類名();
Telphone phone = new Telphone();
- 使用對象:
引用對象的屬性:對象名.屬性
Phone.screen =5;
引用對象的方法:對象名.方法名();
Phone.sendMessage();
3.成員變量和局部變量
- 成員變量
在類中定義,用來描述對象將要有什麼。
- 局部變量
在類的方法中定義,在方法中臨時保存數據。
成員變量和局部變量區別:
(1)作用域不同
局部變量的作用域僅限於定義它的方法。
成員變量的作用域在整個類內部都是可見的。
(2)初始值不同
Java會給成員變量一個初始值,Java不會給局部變量賦予初始值
(3)在同一個方法中,不允許有同名局部變量;在不同的方法中,可以有同名局部變量。
(4)兩類變量同名時,局部變量具有更高的優先級。
4.構造方法
(1)使用new + 構造方法 創建一個新的對象。
(2)構造方法是定義在Java類中的一個用來初始化對象的方法。
(3)構造方法與類同名且沒有返回值。
(4)當沒有指定構造方法時,系統會自動添加無參的構造方法。
(5)當有指定構造方法,無論是有參、無參的構造方法,都不會自動添加無參的構造方法。
(6)構造方法的重載:方法名相同,但參數不同的多個方法,調用時會自動根據不同的參數選擇相應的方法。
(7)構造方法不但可以給對象的屬性賦值,還可以保證給對象的屬性賦一個合理的值。
5.Java中的static使用之靜態變量注意事項:
(1)靜態成員屬於整個類,當系統第一次使用該類時,就會爲其分配內存空間直到該類被卸載纔會進行資源回收!
(2)靜態方法中可以直接調用同類中的靜態成員,但不能直接使用調用非靜態成員。(如果希望在靜態方法中調用非靜態變量,可以通過創建類的對象,然後通過對象來訪問非靜態變量。)
(3)在普通成員方法中,則可以直接訪問同類的非靜態變量和靜態變量。
6.Java中的static使用之靜態初始化塊注意事項:
靜態初始化塊只在類加載時執行,且只會執行一次,同時靜態初始化塊只能給靜態變量賦值,不能初始化普通的成員變量。(使用static修飾初始化塊,成爲靜態初始化塊)
- 封裝
7.1封裝概念及好處
- 概念:
將類的某些信息隱藏在類內部,不允許外部程序直接訪問,而是通過該類提供的方法來實現對隱藏信息的操作和訪問。
- 好處:
- 只能通過規定的方法訪問數據。
- 隱藏類的實例細節,方便修改和實現。
7.2Java中的包
- 包的作用:
管理Java文件,解決同名文件衝突。
- 定義包:package包名
注:必須放在Java源程序的第一行,包名間可以使用“.”號隔開.
- 系統中的包
Java.(功能).(類)
Java.lang.(類) 包含java語言基礎的類。
Java.util(類) 包含java語言中的各種工具類。
Java.io.(類) 包含輸入、輸出相關功能的類。
- 包的使用
- 可以通過import關鍵字,在某個文件使用其它文件中的類。
- Java中,包的命名規範是全小寫字母拼寫。
使用的時候不但可以加載某個包下的所有文件(eg:com.imooc.*),也可以加載某個具體子包下的所有文件(eg:com.imooc.music)。
7.3 java中的訪問修飾符
訪問修飾符 |
本類 |
同包 |
子類 |
其他 |
private |
√ |
|
|
|
默認 |
√ |
√ |
|
|
protected |
√ |
√ |
√ |
|
public |
√ |
√ |
√ |
√ |
7.4.java中的this關鍵字
(1)this關鍵字代表當前對象
this.屬性 操作當前對象的屬性
this.方法 調用當前對象的方法
(2)封裝對象的屬性的時候,經常會使用this關鍵字。
7.5 java中的內部類
內部類(Inner Class)就是定義在另外一個類裏面的類。
作用:
- 內部類提供了更好的封裝,可以把內部類隱藏在外部類之內,不允許同一個包中的其他類訪問該類。
- 內部類的方法可以直接訪問外部類的所有數據,包括私有的數據。
- 內部類所實現的功能使用外部類同樣可以實現,只是有時使用內部類更方便。
內部類可分爲以下幾種:
※成員內部類
※靜態內部類
※方法內部類:就是內部類定義在外部類的方法中,方法內部類只在該方法的內容可見,即只在該方法內可以使用。
※匿名內部類
成員內部類的使用方法:
- Inner類定義在Outer類的內部,相當於Outer類的一個成員變量的位置,Inner類可以使用任意訪問控制符,如public、protected、private等。
- Inner類中定義的test()方法可以直接訪問Outer類中的數據,而不受訪問控制符的影響,如直接訪問Outer類中的私有屬性。
- 定義了成員內部類後,必須使用外部類對象來創建內部類對象,而不能直接去new一個內部類對象,即:內部類 對象名 = 外部類對象.new 內部類();
- 內部類的.class文件總是這樣:外部類名$內部類名.class
靜態內部類就是static修飾的內部類,這種內部類的特點是:
- 靜態內部類不能直接訪問外部類的非靜態成員,但可以通過new 外部類().成員的方式訪問。
- 如果外部類的靜態成員與內部類的成員名稱相同,可通過“類名.靜態成員”訪問外部類的靜態成員;如果外部類的靜態成員與內部類的成員名稱不相同,則可通過“成員名”直接調用外部類的靜態成員。
- 創建 靜態內部類的對象時,不需要外部類的對象,可以直接創建 內部類 對象名 = new 內部類();
方法內部類注意事項:
由於方法內部類不能在外部類的方法以外的地方使用,因此方法內部類不能使用訪問控制符和static修飾符。
- 繼承
8.1繼承的初始化順序
(1)初始化父類再初始子類。
(2)先執行初始化對象中的屬性,再執行構造方法中的初始化。
8.2 Java中的super的使用
Super關鍵字:
在對象的內部使用,可以代表父類對象。
- 訪問父類的屬性
Super.age
- 訪問父類的方法
Super.eat()
Super的應用
子類的構造的過程中必須調用其父類的構造方法。(隱式調用)。
如果子類的構造方法中沒有顯示調用父類的構造方法,則系統默認調用父類無參的構造方法。(super關鍵字)
如果顯示的調用構造方法,必須在子類的構造方法的第一行。例如:
Public Dog(){
Super();
System.out.println(“ddd”);
}
如果子類構造方法中既沒有顯式調用父類的構造方法,而父類又沒有無參的構造方法,則編譯出錯。
8.3 Java中的Object類
Object類是所有類的父類,如果一個類沒有使用extends關鍵字明確標識繼承另外一個類,那麼這個類默認繼承Object類。
Object類中的方法,適合所有子類。
(1)toString()方法
在Object類裏面定義toString()方法的時候返回的對象的哈希code碼(對象地址字符串)。
可以通過重寫toString()方法表示出對象的屬性。
(2)equals()方法
比較的是對象的引用是否指向同一塊內存地址。
Dog dog = new Dog();
一般情況下比較兩個對象時比較他的值是否一致,所以要進行重寫。
- 多態
9.1 多態:對象的多種形態
- 引用多態
父類的引用可以指向本類的對象
父類的引用可以指向子類的對象
- 方法多態
創建本類對象時,調用的方法爲本類方法
創建子類對象時,調用的方法爲子類重寫的方法或者繼承的方法
9.2 引用類型轉換
(1)向上類型轉換(隱式/自動類型轉換),是小類型到大類型的轉換。
(2)向下類型轉換(強制類型轉換),是大類型到小類型的轉換。
(3)instanceof運算符,來解決引用對象的類型,避免類型轉換的安全性問題。(用於判斷一個引用是否是某個類型或某個類型的子類型)
Dog dog = new Dog();
Animal animal = dog;//向上類型轉換 自動類型轉換
Dog dog2 = (Dog)animal;
If(animal instanceof Cat){
Cat cat = (Cat)animal;//1.編譯時Cat類型 2.運行時Dog類型
}else{
System.out.println(“無法進行類型轉換”);
}
9.3 抽象類
(1)概念:抽象類前使用abstract關鍵字修飾,則該類爲抽象類。
(2)應用場景:
a、在某些情況下,某個父類只是知道其子類應該包含怎樣的方法,但無法準確知道這些子類如何實現這些方法。
b、從多個具有相同特徵的類中抽象出一個抽象類,以這個抽象類作爲子類的模板,從而避免了子類設計的隨意性。
(3)作用:
限制規定子類必須實現某些方法,但不關注實現細節。
(4)使用規則:
a、abstract定義抽象類
b、abstract定義抽象方法,只有聲明,不需要實現
c、包含抽象方法的類是抽象類
d、抽象類中可以包含普通的方法,也可以沒有抽象方法
e、抽象類不能直接創建,可以定義引用變量
9.4 接口
(1)接口概念
類是一種具體實現體,而接口定義了某一批類所需要遵守的規範,接口不關心這些類的內部數據,也不關心這些類裏方法的實現細節,它只規定這些類裏必須提供某些方法。(接口就是用來被繼承、被實現的,修飾符一般建議用public.注意:不能使用private和protected修飾接口)
(2)接口定義
和類定義不同,定義接口不再使用class關鍵字,而是使用interface關鍵字。
常量:
接口中的屬性是常量,即使定義時不添加public static final 修飾符,系統也會自動加上。
方法:
接口中的方法只能是抽象方法,總是使用,即使定義時不添加public abstract修飾符,系統也會自動加上。
- 使用接口
一個類可以實現一個或多個接口,實現接口使用implements關鍵字。Java中一個類只能繼承一個父類,是不夠靈活的,通過實現多個接口可以做補充。
繼承父類實現接口的語法爲:
[修飾符]class 類名 extends 父類implements接口1,接口2...
{
類體部分//如果繼承了抽象類,需要實現繼承的抽象方法;
}
如果要繼承父類,繼承父類必須在實現接口之前。
9.5 UML
(1)用例圖(The Use Case Diagram)
用例圖能夠以可視化的方式,表達系統如何滿足所收集的業務規則,以及特定的用戶需求等信息。
(2)序列圖(The Sequence Diagram)
序列圖用於按照交互發生的一系列順序,顯示對象之間的這些交互。
(3)類圖(The Class Diagram)
UML類圖、業務邏輯和所有支持結構一同被用於定義全部的代碼結構。
Java入門第三季
1.異常與異常處理
1.1 Java異常簡介
有異於常態,和正常情況不一樣,有錯誤出現。
阻止當前方法或作用域,稱之爲異常。
1.2 實際應用中的經驗與總結
- 處理運行時異常時,採用邏輯去合理規避同時輔助try-catch處理
- 在多重catch塊後面,可以加一個catch(Exception)來處理可能會被遺漏的異常
- 對於不確定的代碼,也可以加上try-catch,處理潛在的異常
- 儘量去處理異常,切忌只是簡單的調用printStackTrace()去打印輸出
- 具體如何處理異常,要根據不同的業務需求和異常類型去決定
- 儘量添加finally語句塊去釋放佔用的資源
- Java中的字符串
2.1 “==”和equals()區別
- ==:判斷兩個字符串在內存中首地址是否相同,即判斷是否是同一個字符串對象。
- equals():比較存儲在兩個字符串對象中的內容是否一致。
- Java中必須瞭解的常用類
3.1 基本類型和包裝類之間的對應關係
基本類型 |
對應的包裝類 |
byte |
Byte |
short |
Short |
int |
Integer |
long |
Long |
float |
Float |
double |
Double |
char |
Character |
boolean |
Boolean |
3.2 裝箱和拆箱
裝箱:把基本類型轉換成包裝類,使其具有對象的性質,又可分爲手動裝箱和自動裝箱。
int i = 10;//定義一個int基本類型值
Integer x = new Integer(i);//手動裝箱
Integer y = i;//自動裝箱
拆箱:和裝箱相反,把包裝類對象轉換成基本類型的值,又可分爲手動拆箱和自動拆箱。
Integer j = new Integer(8);//定義一個Integer包裝類對象,值爲8
int m = j.intValue();//手動拆箱爲int類型
Int n = j;//自動拆箱爲int 類型
3.3 基本數據類型和字符串直接轉換
- 基本類型轉換爲字符串有三種方法:
- 使用包裝類toString()方法
- 使用String類的valueOf()方法
- 用一個空字符串加上基本類型,得到的就是基本類型數據對應的字符串。
例子:
//將基本類型轉換爲字符串
int c = 10;
String str1 = Integer.toString(c);//方法一
String str2 = String.valueOf(c);//方法二
String str3 = c + “”;//方法三
- 將字符串轉換成基本類型有兩種方法:
- 調用包裝類parseXxx靜態方法
- 調用包裝類valueOf()方法轉換爲基本類型的包裝類,會自動拆箱
例子:
//將字符串轉換爲基本類型
String str = “8”;
Int d = Integer.parseInt(str);//方法一
Int e = Integer.valueOf(str);//方法二
3.4 SimpleDateFormat類使用
可以使用java.text包中的SimpleDateFormat類來對日期時間進行格式化,可以將日期轉換爲指定格式的文本,也可將文本轉換爲日期。
- 使用format()方法將日期轉換爲指定格式的文本
例子:
//創建Data對象,表示當前時間
Date d = new Date();
//創建SimpleDateFormat對象,指定目標格式
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
//調用format方法,格式時間,轉換爲指定格式字符串
String today = sdf.format(d);
//輸出轉換後的字符串
System.out.println(today);
- 使用parse()方法將文本轉換爲日期
例子:
//創建日期格式的字符串
String day = “2014年02月14日10:30:25”;
//創建SimpleDateFormat對象,指定字符串的日期格式
SimpleDateFormat df = new SimpleDateFormat(“yyyy年MM月dd日HH:mm:ss”);
//調用parse()方法,將字符串轉換爲日期
Date date = df.parse(day);
//輸出轉換後的時間
System.out.println(“當前時間:”+date);
注意:
- 調用SimpleDateFormat對象的parse()方法時可能會出現轉換異常,即ParseException,因此需要進行異常處理。
- 使用Date類時需要導入java.util包,使用SimpleDateFormat時需要導入java.text包。
3.5 Calendar類的應用
Java.util.Calendar類是一個抽象類,可以通過調用getInstance()靜態方法獲取一個Calendar對象,此對此已由當前日期時間初始化,即默認代表當前時間,如Calendar c = Calendar.getInstance();
例子:
Calendar c = Calendar.getInstance();//創建Calendar對象
int year = c.get(Calendar.YEAR);//獲取年
int month = c.get(Calendar.MONTH) + 1;
- Java中的集合框架
4.1 Collection接口
- 是List、Set和Queue接口的父接口
- 定義了可用於操作List、Set和Queue的方法--增刪改查
4.2 List接口及其實現類--ArrayList
- List是元素有序並且可以重複的集合,被稱爲序列
- List可以精確的控制每個元素的插入位置,或刪除某個位置元素
- ArrayList---數組序列,是List的一個重要實現類
- ArrayList底層是由數組實現的。
4.3 泛型
集合中的元素,可以是任意類型的對象(對象的引用),如果把某個對象放入集合,則會忽略他的類型,而把他當做Object處理
泛型則是規定了某個集合只可以存放特定類型的對象(會在編譯其對類型進行檢查,可以直接按指定類型獲取集合元素,泛型結合可以添加泛型的子類型的對象實例,泛型結合中,不能添加泛型規定的類型及其子類型以外的對象,否則會報錯!)
泛型集合中的限定類型不能使用基本數據類型,可以通過使用包裝類限定允許存入的基本數據類型。
4.4 Set接口及其實現類---HashSet
(1)Set是元素無序並且不可以重複的集合,被稱爲集。
(2)HashSet--哈希集,是Set的一個重要實現類。
4.5 Map接口
Map提供了一種映射關係,其中的元素是以鍵值對(key -value)的形式存儲的,能夠實現根據key快速查找value。
Map中的鍵值對以Entry類型的對象實例形式存在。
鍵(key值)不可重複,value值可以
每個鍵最多隻能映射到一個值
Map支持泛型,形式如:Map<K,V>
4.6 HashMap類
HashMap是Map的一個重要實現類,也是最常用的,基於哈希表實現。
HashMap中的Entry對象是無序排列的
Key值和value值都可以爲null,但是一個HashMap只能有一個key值爲null的映射(key值不可以重複)。
4.7 Comparable接口--可比較的
實現該接口表示:這個類的實例可以比較大小,可以進行自然排序。
定義了默認的比較規則
其實現類需實現compareTo()方法
compareTo()方法返回正數表示大,負數表示小,0表示相等
4.8 Comparator接口--比較工具接口
用於定義臨時比較規則,而不是默認比較規則
其實現類需要實現compare()方法
Comparator和Comparable都是Java集合框架的成員
JAVA遇見HTML---Servlet篇
- Servlet
Servlet是在服務器上運行的小程序,一個Servlet就是一個Java類,並且可以通過“請求-響應”編程模型來訪問的這個駐留在服務器內存裏的Servlet程序。
1.1 Tomcat容器等級
Tomcat的容器分爲四個等級,Servlet的容器管理Context容器,一個Context對應一個Web工程。
1.2 編寫Servlet步驟
- 繼承HttpServlet
- 重寫doGet()或者doPost()方法
- 在web.xml中註冊Servlet
1.3 Get方式請求HelloServlet
1.4 Servlet生命週期
- 初始化階段,調用init()方法
- 響應客戶請求階段,調用service()方法。由service()方法根據提交方式選擇執行doGet()或者doPost()方法。
- 終止階段,調用destroy()方法。
1.5 Tomcat裝載Servlet的三種情況
在下列時刻Servlet容器裝載Servlet:
- Servlet容器啓動時自動裝載某些Servlet,實現它只需要在web.xml文件中的<Servlet></Servlet>之間添加如下代碼:<loadon-startup>1</loadon-startup>數字越小表示優先級別越高。
- 在Servlet容器啓動後,客戶首次向Servlet發送請求。
- Servlet類文件被更新後,重新裝載Servlet。
- Servlet被裝載後,Servlet容器創建一個Servlet實例並且調用Servlet的init()方法進行初始化。在Servlet的整個生命週期內,init()方法只被調用一次。
1.6 Servlet與九大內置對象
JSP對象 |
怎樣獲得 |
out |
resp.getWriter |
request |
service方法中的req參數 |
response |
Service方法中的resp參數 |
session |
req.getSession()函數 |
application |
getServletContext()函數 |
exception |
Throwable |
page |
this |
pageContext |
PageContext |
Config |
getServletConfig函數 |
1.7 Servlet路徑跳轉
(1)請求重定向方式跳轉到test.jsp,當前路徑是ServletPathDirection/servlet,而test.jsp在項目根目錄下,則:
response.sendRedirect(request.getContextPath()+”/test.jsp”);
其中使用request.getContextPath獲得上下文對象。
- 使用服務器內部跳轉(“/”代表根目錄或者“../”)
request.getRequestDispatcher("/test.jsp").forward(request, response);
- 應用MVC架構實現項目
2.1 Model1簡介(JSP+JavaBean)
2.2 Model2簡介(Java Web的Model2開發模型就是MVC思想的體現。)
JAVA遇見HTML--JSP篇
- JAVA WEB簡介
1.1 Tomcat服務器的目錄結構
目錄 |
說明 |
/bin |
存放各種平臺下用於啓動和停止Tomcat的命令文件 |
/conf |
存放Tomcat服務器的各種配置文件 |
/lib |
存放Tomcat服務器所需的各種JAR文件 |
/logs |
存放Tomcat的日誌文件 |
/temp |
Tomcat運行時用於存放臨時文件 |
/webapps |
當發佈Web應用時,默認會將Web應用的文件發佈於此目錄中 |
/work |
Tomcat把由JSP生成的Servlet放於此目錄下 |
1.2 WEB-INF目錄結構
- WEB-INF是Java的WEB應用的安全目錄。所謂安全就是客戶端無法訪問,只有服務端可以訪問的目錄。
- Web.xml,項目部署文件。
- Classes文件夾,用以放置*.class文件。
- Lib文件夾,用於存放需要的jar包。
1.3 修改Tomcat服務器默認端口
修改conf/server.xml文件
- JSP基礎語法
2.1 JSP簡介
JSP全名爲Java Server Pages,其根本是一個簡化的Servlet設計,他實現了在Java當中使用HTML標籤。Jsp是一種動態網頁技術標準也是JAVAEE的標準。JSP與Servlet一樣,是在服務器端執行的。
2.2 JSP頁面元素構成:
JSP頁面組成部分包括:指令、表達式、小腳本、聲明、註釋、靜態內容。
JSP指令:
- Page指令:通常位於jsp頁面的頂端,同一個頁面可以有多個page指令。
- Include指令:將一個外部文件嵌入到當前JSP文件中,同時解析這個頁面中的JSP語句。
- Tablib指令:使用標籤庫定義新的自定義標籤,在JSP頁面中啓用定製行爲。
2.3 JSP指令之page指令
Page指令語法:
<%@page 屬性1=”屬性值” 屬性2=”屬性值1,屬性值2”...
屬性n=”屬性值n”%>
屬性 |
描述 |
默認值 |
language |
指定JSP頁面使用的腳本語言 |
java |
import |
通過該屬性來引用腳本語言中使用到的類文件 |
無 |
contentType |
用來指定JSP頁面所採用的編碼方式 |
Text/html,ISO-8859-1 |
2.4 JSP註釋
在JSP頁面的註釋。
HTML的註釋:
<!--html註釋--> //客戶端可見
JSP的註釋:
<%--html註釋--%> //客戶端不可見
JSP腳本註釋:
//單行註釋
/**/多行註釋
2.5 JSP腳本
在JSP頁面中執行的java代碼。
語法:
<% Java代碼%>
2.6 JSP聲明
在JSP頁面中定義變量或者方法。
語法:
<%! Java代碼%>
2.7 JSP表達式
在JSP頁面中執行的表達式。
語法:
<%= 表達式 %> //注意:表達式不以分好結束
2.8 JSP頁面聲明週期
其中jspService()方法被調用來處理客戶端的請求。對每一個請求,JSP引擎創建一個新的線程來處理該請求。如果有多個客戶端同事請求該JSP文件,則JSP引擎會創建多個線程。每個客戶端請求對應一個線程。以多個線程方式執行可以大大降低對系統的資源需求,提高系統的併發量及響應時間。但也要注意多線程的編程帶來的同步問題,由於該Servlet始終駐留內存,所以響應是非常快的。
- JSP內置對象(上)
3.1 內置對象簡介
JSP內置對象是Web容器創建的一組對象,不使用new關鍵字就可以使用的內置對象。
常用的九大JSP內置對象:
Out、request、response、session、application、page、pageContext、exception、config
3.2 Out對象
Out對象是JspWriter類的實例,是向客戶端輸出內容常用的對象。
常用方法如下:
- void println()向客戶端打印字符串
- void clear()清除緩衝區的內容,如果在flush之後調用會拋出異常。
- Void clearBuffer();清除緩衝區的內容,如果在flush之後調用不會拋出異常。
- void flush()將緩衝區內容輸出到客戶端
- int getBufferSize() 返回緩衝區以字節數的大小,如不設緩衝區則爲0
- int getRemaining()返回緩衝區還剩餘多少可用
- boolean isAutoFlush()返回緩衝區滿時,是自動清空還是拋出異常
- Void close()關閉輸出流。
3.3 get與post區別
<from name = “regForm” action =”動作” method=”提交方式”></form>
表單有兩種提交方式:get與post
- get:以明文的方式通過URL提交數據,數據在URL中可以看到。提交的數據最多不超過2KB。安全性較低但效率比post方式高。適合提交數據量不大,安全性不高的數據。比如:搜索、查詢等功能。
- Post:將用戶提交的信息封裝在HTML HEADER內。適合提交數據量大,安全性高的用戶信息。比如:註冊、修改、上傳等功能。
3.4 request對象
客戶端的請求信息被封裝在request對象中,通過它才能瞭解到客戶的需求,然後做出響應。它是HttpServletRequest類的實例。Request對象具有請求域,即完成客戶端的請求之前,該對象一直有效。常用方法如下:
- String getParameter(String name)返回name指定參數的參數值
- String []getParameterValues(String name)返回包含參數name的所有值的數組
- Void setAttribute(String name);存儲此請求中的屬性
- Object getAttribute(String name)返回指定屬性的屬性值
- String getContentType()得到請求體的MIME類型
- String getProtocol()返回請求用的協議類型及版本號
- String getServerName()返回接受請求的服務器主機名
- Int getServerPort()返回服務器接受此請求所用的端口號
- String getCharacterEncoding()返回字符編碼方式
- Void setCharacterEncoding()設置請求的字符編碼方式
- Int getContentLength()返回請求體的長度(以字節數)
- String getRemoteAddr()返回發送此請求的客戶端IP地址
- String getRealPath(String path) 返回一虛擬路徑的真實路徑
- String request.getContextPath() 返回上下文路徑
3.5 response對象
response對象包含了響應客戶請求的有關信息,但在JSP中很少直接用到它。它是HttpServletResponse類的實例。Response對象具有頁面作用域,即訪問一個頁面時,該頁面內的response對象只能對這次訪問有效,其他頁面的response對象對當前頁面無效。常用方法如下:
- String getCharacterEncoding()返回響應用的是何種字符編碼
- void setContentType(String type)設置響應的MIME類型
- PrintWriter getWriter() 返回可以向客戶端輸出字符的一個對象(注意比較:PrintWriter與內置out對象的區別,輸出總是提前與內置out對象)
- sendRedirect(java.lang.String location)重新定向客戶端的請求。
3.6 請求轉發與請求重定向區別
- 請求重定向:客戶端行爲,response.sendRedirect(),從本質上講等同於兩次請求,前一次的請求對象不會保存,地址欄的URL地址會改變。
- 請求轉發:服務器行爲,request.getRequestDispatcher().forward(req,resp);是一次請求,轉發後請求對象會保存,地址欄的URL地址不會改變。
- JSP內置對象(下)
4.1什麼是session
- session表示客戶端與服務器的一次會話。
- Web中的session指的是用戶在瀏覽某個網站時,從進入網站到瀏覽器關閉所經過的這段時間,也就是用戶瀏覽這個網站所花費的時間。
- 從上述定義中可以看到,session實際上是一個特定的時間概念
4.2 session對象
- session對象是一個JSP內置對象。
- Session對象在第一個JSP頁面被裝載時自動創建,完成會話期管理。
- 從一個客戶打開瀏覽器並連接到服務器開始,到客戶關閉瀏覽器離開這個服務器結束,被稱爲一個會話。
- 當一個客戶訪問一個服務器時,可能會在服務器的幾個頁面之間切換,服務器應當通過某種辦法知道這個一個客戶,就需要session對象。
- Session對象是HttpSession類的實例。
4.3 session對象常用方法如下:
- long getCreationTime():返回session創建時間。
- pulibc String getId():返回session創建時JSP引擎爲它設的唯一ID號
- public Object setAttribute(String name,Object value):使用指定名稱將對象綁定到此會話。
- Public Object getAttribute(String name): 返回與此會話中的指定名稱綁定在一起的對象,如果沒有對象綁定在該名稱下,則返回null.
- String []getValueNames():返回一個包含此session種所有可用屬性的數組。
- Int getMaxInactiveInterval():返回兩次請求間隔多長時間此seesion被取消(單位秒)。
4.4 session的聲明週期
- 創建:
當客戶端第一次訪問某個jsp或者servlet時候,服務器會爲當前會話創建一個sessionId,每次客戶端向服務端發送請求時,都會將此sessionId攜帶過去,服務端會對此sessionId進行校驗。
- 活動:
某次會話當中通過超鏈接打開的新頁面屬於同一次會話。
只要當前會話頁面沒有全部關閉,重新打開新的瀏覽器窗口訪問同一項目資源時屬於同一次會話。
除非本次會話的所有頁面都關閉後再重新訪問某個JSP或者servlet將會創建新的會話。
注意事項:注意原有會話還存在,只是這個舊的sessionId仍然存在於服務端,只不過再也沒有客戶端會攜帶它然後交予服務端校驗。
- 銷燬:
Seesion的銷燬只有三種方式:
※ 調用了session.invalidate()方法。
※ session過期(超時)
※ 服務器重新啓動
※ Tomcat 默認session超時時間爲30分鐘。
※ 設置session超時有兩種方式:
- session.setMaxInactiveInterval(時間);//單位是秒
- 在web.xml配置
<session-config><session-timeout>10</session-timeout></session-config>//單位是分鐘。
4.5 application對象
(1)application對象實現了用戶間數據的共享,可存放全局變量。
(2)application開始於服務器的啓動,終止於服務器的關閉。
(3)在用戶的前後連接或不同用戶之間的連接中,可以對application對象的同一屬性進行操作。
(4)在任何地方對application對象屬性的操作,都將影響到其他用戶對此的訪問。
(5)服務器的啓動和關閉決定了application對象的生命。
(6)application對象是ServletContext類的實例。
4.6 application對象常用方法如下:
(1)public void setAttribute(String name,Object value)使用指定名稱將對象綁定到此會話。
(2)public Object getAttribute(String name)返回與此會話中的指定名稱綁定在一起的對象,如果沒有對象綁定在該名稱下,則返回null.
(3)Enumeration getAttributeNames()返回所有可用屬性名的枚舉。
(4)String getServerInfo()返回JSP(SERVLET)引擎名及版本號。
4.7 page對象
Page對象就是指向當前JSP頁面本身,有點像類中的this指針,它是java.lang.Object類的實例。常用方法如下:
- class getClass()返回此Object的類。
- Int hasCode()返回此Object的hash碼
- boolean equals(Object obj)判斷此Object是否與指定的Object對象相等。
- void copy(Object obj)把此Object拷貝到指定的Object對象中
- Object clone()克隆此Object對象
- String toString()把此Object對象轉換成String類的對象
- void notify()喚醒一個等待的線程
- void notifyAll()喚醒所有等待的線程
- void wait(int timeout)使一個線程處於等待直到timeout結束或被喚醒。
- void wait()使一個線程處於等待直到被喚醒。
4.8 pageContext對象
·pageContext對象提供了對JSP頁面內所有的對象及名字空間的訪問
·pageContext對象可以訪問到本頁所在的session,也可以取本頁面所在的application的某一屬性值
·pageContext對象相當於頁面中所有功能的集大成者
·pageContext對象的本類名也叫pageContext.
常用方法如下:
- JspWriter getOut() 返回當前客戶端響應被使用的JspWriter流(out)
- HttpSession getSession()返回當前頁中的HttpSession對象(session)
- Object getPage()返回當前頁的Object對象(page)
- ServletRequest getRequest()返回當前頁的ServletRequest對象(request)
- ServletResponse getResponse()返回當前頁的ServletResponse對象(response)
- void setAttribute(String name,Object attribute)設置屬性及屬性值
- Object getAttribute(String name,int scope)在指定範圍內取屬性的值
- int getAttributeScope(String name)返回某屬性的作用範圍
- void forward(String relativeUrlPath)使當前頁面重導到另一頁面
- void include(String relativeUrlPath)在當前位置包含另一文件
4.9 Config對象
Config對象是在一個Servlet初始化是,JSP引擎向它傳遞信息用的,此信息包括Servlet初始化時所要用到的參數(通過屬性名和屬性值構成)以及服務器的有關信息(通過傳遞一個ServletContext對象),常用方法如下:
- ServletContext getServletContext() 返回含有服務器相關信息的ServletContext對象。
- String getInitParameter(String name) 返回初始化參數的值
- Enumeration getInitParameterNames() 返回Servlet初始化所需所有參數的枚舉。
4.10 Exception對象
Exception對象是一個異常對象,當一個頁面在運行過程中發生了異常,就產生這個對象。如果一個JSP頁面要應用此對象,就必須把isErrorPage設爲true,否則無法編譯。他實際上是java.lang.Throwable的對象,常用方法如下:
- String getMessage() 返回錯誤異常的消息
- String toString()返回關於異常的簡短描述消息
- Void printStackTrace() 顯示異常及其棧軌跡
- Throwable FillInStackTrace()重寫異常的執行棧軌跡
- JavaBeans
Javabeans就是符合某種特定的規範的Java類。使用Javabeans的好處是解決代碼重複編寫,減少代碼冗餘,功能區分明確,提高了代碼的維護性。
5.1 Javabean的設計原則
公有類、無參的公有構造方法、屬性私有、getter和setter方法。
例如:
//設計學生類
public class Students{
private String name;
private int age;
public Students(){}
public void setName(String name){this.name=name;}
Public String getName(){return this.name;}
public void setAge(int age){this.age=age;}
public int getAge(){return this.age;}
}
5.2 什麼是Jsp動作
JSP動作元素(action elements),動作元素爲請求處理階段提供信息。動作元素遵循XML元素的語法,有一個包含元素名的開始標籤,可以有屬性、可選的內容、與開始標籤匹配的結束標籤。主要包含以下五類
第一類是與存取JavaBean有關的,包括:
<jsp:useBean><jsp:setProperty><jsp:getProperty>
第二類JSP1.2就開始有的基本元素,包括6個動作元素
<jsp:include><jsp:forward><jsp:param><jsp:plugin><jsp:params><jsp:fallback>
第三類是JSP2.0新增加的元素,主要與JSP Document有關,包括六個元素
<jsp:root><jsp:declaration><jsp:scriptlet><jsp:expression><jsp:text><jsp:output>
第四類是JSP2.0新增的動作元素,主要用來動態生成XML元素標籤的值,包括3個動作<jsp:attribute><jsp:body><jsp:element>
第五類是JSP2.0新增的動作元素,主要是用在Tag File中,有2個元素
<jsp:invoke><jsp:dobody>
5.3 在JSP頁面中如何使用Javabeans
(1)像使用普通java類一樣,創建javabean實例。
(2)在jsp頁面中通常使用jsp動作標籤使用javabean.
其中:
※ <jsp:useBeans>作用:在JSP頁面中實例化或者在指定範圍內使用javabean:
<jsp:useBean id=”標識符” class=”java類名” scope=”作用範圍”/>
※ <jsp:setProperty>作用:給已經實例化的Javabean對象的屬性賦值,一共有四種形式。
<jsp:setProperty name=”JavaBean實例名” property=”*”/>(跟表單關聯)
<jsp:setProperty name=”JavaBean實例名” property=”JavaBean屬性名”/>(跟表單關聯)
<jsp:setProperty name=”JavaBean實例名” property=”JavaBean屬性名” value=”BeanValue”/>(手工設置)
<jsp:setProperty name =”JavaBean實例名” property =”propertyName” param=”request對象中的參數名”/>(跟request參數關聯)
※ <jsp:getProperty>作用:獲取指定Javabean對象的屬性值
<jsp:getProperty name=”JavaBean實例名” property=”屬性名”/>
5.4 Javabean的四個作用域範圍
說明:使用useBeans的scope屬性可以用來指定javabean的作用範圍。
· page//僅在當前頁面有效
· request//可以通過HttpRequest.getAttribute()方法取得JavaBean對象
· session //可以通過HttpSession.getAttribute()方法取得JavaBean對象。
· application //可以通過application.getAttribute()方法取得Javabean對象。
5.5 Model1簡介
- JSP狀態管理
6.1 http協議的無狀態性
無狀態是指,當瀏覽器發送請求給服務器的時候,服務器響應客戶端請求。但是當同一個瀏覽器再次發送請求給服務器的時候,服務器並不知道它就是剛纔那個瀏覽器。
簡單地說,就是服務器不會去記得你,所以就是無狀態協議。
保存用戶的狀態的兩大機制:Session、Cookie
6.2 Cookie概述
(1)什麼是cookie?
Cookie:中文名稱爲“小甜餅”,是web服務器保存在客戶端的一系列文本信息。
典型應用一:判定註冊用戶是否已經登錄網站。
典型應用二:“購物車”的處理。
(2)Cookie的作用
· 對特定對象的追蹤
· 保存用戶網頁瀏覽記錄與習慣
· 簡化登錄
安全風險:容易泄露用戶信息。
(3)JSP中創建與使用Cookie
常用方法:
方法名稱 |
說明 |
void setMaxAge(int expiry) |
設置cookie的有效期,以秒爲單位 |
void setValue(String value) |
在cookie創建後,對cookie進行賦值 |
String getName() |
獲取cookie的名稱 |
String getValue() |
獲取cookie的值 |
int getMaxAge() |
獲取cookie的有效時間,以秒爲單位 |
(4)Session與Cookie對比
session |
cookie |
在服務器端保存用戶信息 |
在客戶端保存用戶信息 |
Session中保存的是Object類型 |
Cookie保存的是String類型 |
隨會話的結束而將其存儲的數據銷燬 |
Cookie可以長期保存在客戶端 |
保存重要的信息 |
保存不重要的用戶信息 |
- JSP指令與動作元素
7.1 include指令
語法:
<%@ include file=”URL”%>
7.2 include動作(動作標籤)
語法:
<jsp:include page=”URL” flush=”true|false”/>其中:page:要包含的頁面,flush:被包含的頁面是否從緩衝區讀取。
7.3 include指令與include動作的區別
|
Include指令 |
jsp:include動作 |
語法格式 |
<%@ include file=”..” %> |
<jsp:include page=”..”> |
發生作用的時間 |
頁面轉換期間 |
請求期間 |
包含的內容 |
文件的實際內容 |
頁面的輸出 |
轉換成的Servlet |
主頁面和包含頁面轉換一個Servlet |
主頁面和包含頁面轉換爲獨立的Servlet |
編譯時間 |
較慢--資源必須被解析 |
較快 |
執行時間 |
稍快 |
較慢--每次資源必須被解析 |
7.4 forward動作
語法:
<jsp:forward page=”URL”/>
等同於:
Request.getRequestDispatcher(“/url”).forward(request,response);
7.5 param動作
語法:
<jsp:param name=”參數名” value=”參數值”>
常常與<jsp:forward>一起使用,作爲其的子標籤。
深入淺出Java多線程
- Java多線程基礎概念介紹
1.1 進程
程序(任務)的執行過程,持有資源(共享內存,共享文件)和線程。
1.2 線程
線程是系統在洪最小的執行單元,同一進程有多個線程。線程共享進程的資源。
- Java線程初體驗
2.1 Thread常用方法
類別 |
方法簽名 |
|
線程的創建 |
Thread() |
|
Thread(String name) |
|
|
Thread(Runnable target) |
|
|
Thread(Runnable target,String name) |
|
|
線程的方法 |
void start() |
啓動線程 |
static void sleep(long millis) |
線程休眠 |
|
static void sleep(long millis,int nanos) |
||
void join() |
使其他線程等待當前線程終止 |
|
void join(long millis) |
||
void join(long millis,int nanos) |
||
static void yield() |
當前運行線程釋放處理器資源 |
|
獲取線程引用 |
static Thread currentThread() |
返回當前運行的線程引用 |
- 使用進程注意事項
- 停止線程不要使用stop()、interrupt()方法,使用退出標誌停止線程。
- 使用volatile保證了線程可以正確的讀取其他線程寫入的值。(volatile boolean keepRunning = true;)
- 線程交互
4.1 爭用條件
當多個線程同時共享訪問同一數據(內存區域)時,每個線程都嘗試操作該數據,從而導致數據被破壞,這種線程稱爲爭用條件。
4.2 互斥與同步
相交進程之間的關係主要有兩種,同步與互斥。所謂互斥,是指散步在不同進程之間的若干程序片斷,當某個進程運行其中一個程序片段時,其他進程就不能運行它們之中的任一程序片段,只能等到該進程運行完這個程序片段後纔可以運行。所謂同步,是指散步在不同進程之間的若干程序片段,他們的運行必須嚴格按照規定的某種先後次序來運行,這種先後次序依賴於要完成的特定的任務。
顯然,同步是一種更爲複雜的互斥,而互斥是一種特殊的同步。
也就是說互斥是兩個線程之間不可以同時運行,他們會相互排斥,必須等待一個線程運行完畢,另一個才能運行,而同步也是不能同時運行,但他是必須要安照某種次序來運行相應的線程(也是一種互斥)!
總結:互斥:是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。
同步:是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源。
互斥的實現:synchronized(intrinsic lock)
同步的實現:wait()/notify()/notifyAll() 都是object對象而非Thread類
反射--Java高級開發必須懂的
- Class類的使用
1.1 Class類
- 在面向對象的世界裏,萬事萬物皆對象。基本的數據類型(void關鍵字什麼的)都存在類類型。
類是對象,類是java.lang.Class類的實例對象。(任何一個類都是Class的實例對象,這個實例對象有三種表示方式)
例子:Dog dog1 = new Dog();
//第一種表示方式--->實際在告訴我們任何一個類都有一個隱含的靜態成員變量class. Class c1 = Dog.class;
//第二種表達方式 已經知道該類的對象通過getClass方法
Class c2 = dog1 .getClass();
//官網 c1,c2表示了Dog類的類類型(class type)
//第三種表達方式
Class c3 = null;
c3 = Class.forName(“com.imooc.reflect.Dog”);
//我們可以通過類的類類型創建該類的對象實例-->通過c1 or c2 or c3創建Dog的類類型。Dog dog = (Dog)c1.newInstance();//需要有無參數的構造方法
- Java動態加載類
new 創建對象 是靜態加載類,在編譯時刻就需要加載所有的可能用到的類。通過動態加載類可以解決該問題。
動態加載類,在運行時刻加載
示例代碼:
(1)public class OfficeBetter {
public static void main(String[] args) {
try {
//動態加載類,在運行時刻加載
//Class c = Class.forName("com.immoc.reflect.Word");
Class c = Class.forName(args[0]);
//通過類類型,創建該類對象
OfficeAble oa = (OfficeAble)c.newInstance();
oa.start();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
(2)public interface OfficeAble {
public void start();
}
(3)public class Word implements OfficeAble{
@Override
public void start() {
// TODO Auto-generated method stub
System.out.println("word.....start");
}
}
(4)public class Excel implements OfficeAble{
@Override
public void start() {
// TODO Auto-generated method stub
System.out.println("Excel.....start");
}
}
- 方法的反射
- 如何獲取某個方法
方法的名稱和方法的參數列表才能唯一決定某個方法。
- 方法反射的操作
Method.invoke(對象,參數列表)
- 通過Class,Method來認識泛型的本質
反射的操作都是編譯之後的操作
如下代碼示例:
ArrayList list = new ArrayList();
ArrayList<String> list1 = new ArrayList<String>();
list1.add("hello");
Class c1 = list.getClass();
Class c2 = list1.getClass();
System.out.println(c1==c2);//true
其中,c1==c2結果返回true 說明編譯之後集合的泛型是去泛型化的。Java中集合的泛型是防止錯誤輸入的,只在編譯階段有效,繞過編譯就無效了。我們可以通過方法的反射來繞過編譯。
如下代碼示例:
try {
Method m = c2.getMethod("add", Object.class);
m.invoke(list1, 20);
System.out.println(list1.size());
System.out.println(list1);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
文件傳輸基礎--Java IO流
- 文件的編碼
- GBK編碼中文佔用2個字節,英文佔用1個字節
- UTF-8編碼中文佔用3個字節,英文佔用1個字節。
- JAVA是雙字節編碼utf-16be,utf-16be 中文佔用2個字節,
- File常用API介紹
(1)Java.io.File類用於表示文件(目錄)
File類只用於表示文件(目錄)的信息(名稱、大小等),不能用於文件內容的訪問。 (2)RandomAcessFile java提供的對文件內容的訪問,既可以讀文件,也可以寫文件。RandomAcessFile支持隨機訪問文件,可以訪問文件的任意位置。
- Java文件模型:在硬盤上的文件是 byte byte byte存儲的,是數據的集合。
- 打開文件:有兩種模式”rw”(讀寫)”r”(只讀)
RandomAccessFile raf = new RandomAccessFile(file,”rw”);文件指針,打開文件時指針在開頭pointer = 0;
- 寫方法
raf.write(int)--->只寫一個字節(後8位),同事指針指向下一個字節位置,準備再次寫入。
- 讀方法
int b = raf.read() --->讀一個字節
- 文件讀寫完成以後一定要關閉(Oracle官方說明)。
- 字節流
3.1 InputStream、OutputStream
InputStream抽象了應用程序讀取數據的方式,OutputStream抽象了應用程序寫出數據的方式。
3.2 EOF = End 讀到-1就讀到結尾
3.3 輸入流基本方法
//把文件作爲字節流進行讀操作
FileInputStream in = new FileInputStream(fileName);
int b = in.read();讀取一個字節無符號填充到int低八位。-1是EOF
in.read(byte[]buf);讀取數據填充到字節數組buf
In.read(byte[]buf,int start,int size);讀取數據到字節數組buf,從buf的start位置開始存放size長度的數據。
3.4 輸出流基本方法
//如果該文件不存在,則直接創建,如果存在,刪除後創建
FileOutputStream out = new FileOutputStream(“demo/out.data”);
out.write(int b);寫出一個byte到流,b的低8位
out.write(byte[] buf)將buf字節數組寫入到流
out.write(byte []buf,int start,int size);字節數組buf從start位置開始寫size長度的字節到流。
3.5 FileInputStream- ->具體實現了在文件上讀取數據
3.6 FileOutputStream 實現了向文件中寫出byte數據的方法
3.7 字節流之數據輸入輸出流
DataOutputStream/DataInputStram 對”流’功能的擴展,可以更加封邊的讀取int,long,字符等類型數據。對於DataOutputStream而言有writeInt()/writeDouble()/writeUTF()
3.8 BufferedInputStream&BufferedOutputStream
這兩個流類爲IO提供了帶緩衝區的操作,一般打開文件進行寫入或讀取操作時,都會加上緩衝,這種流模式提高了IO的性能。從應用程序中把輸入放入文件,相當於將一缸水倒入到另一缸水。
FileOutputStream --->write()方法相當於一滴一滴的把水“轉移”過去。
DataOutputStream --->writeXxx()方法會方便一些,相當於一瓢一瓢把水“轉移”過去。
BufferedOutputStream --->write方法更方便,相當於一瓢一瓢先放入桶中,再從桶中倒入另一缸中。
- 字符流
4.1 認識文本和文本文件
Java的文本(char)是16位無符號整數,是字符的unicode編碼(雙字節編碼)。
文件是byte byte byte...的數據序列
文本文件是文本(char)序列按照某種編碼方案(utf-8、utf-16be,gbk)序列爲byte的存儲結果。
4.2 字符流(Read Writer)操作的是文本、文本文件。
字符的處理,一次處理一個字符
字符的底層仍然是基本的字符序列。
字符流的基本實現:
InputStreamReader 完成byte流解析爲char流,按照編碼解析
OutputStreamWriter 提供char流到byte流,按照編碼處理。
4.3 FileReader/FileWriter
4.4 字符流的過濾器
BufferedReader --->readLine 一次讀一行
BufferedWriter/PrintWriter --->寫一行
- 對象的序列化和反序列化
- 對象的序列化,就是將Object轉換成byte序列,反之叫對象的反序列化。
- 序列化流(ObjectOutputStream),是過濾流---writeObject
反序列化流(ObjectInputStream)---readObject - 序列化接口(Serializable)
對象必須實現序列化接口才能進行序列化,否則將出現異常。這個接口沒有任何方法,只是一個標準。 - transient:對象屬性加上transient關鍵字後不會進行jvm默認的序列化,也可以自己完成這個元素的序列化。writeObject、readObject方法可參看ArrayList源碼
序列化參考代碼:
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
s.defaultWriteObject();//把jvm能默認序列化的元素進行序列化
s.writeInt(stuage);//自己完成stuage的序列化
}
反序列化參考代碼:
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException,ClassNotFoundException{
s.defaultReadObject();//把jvm能默認反序列化的元素進行反序列化操作t
this.stuage = s.readInt();//自己完成stuage的反序列化操作
}
- 序列化中子類和父類構造函數的調用問題
一個類實現了序列化接口,那麼其子類都可以進行序列化。
對子類對象進行反序列化操作時,如果其父類沒有實現序列化接口,那麼其父類的構造函數會被調用。
二進制基礎
- 二進制位運算
運算符 |
運算 |
示例 |
& |
與運算 |
6 & 3 = 2 |
| |
或運算 |
6 | 3 = 7 |
^ |
異或運算 |
6 ^ 3 = 5 |
~ |
反碼 |
~6 = -7 |
<< |
左移 |
3 << 2 = 12 3*2*2 = 12 |
>> |
右移 |
3 >> 1 = 1 3/2 = 1 |
>>> |
無符號右移 |
3 >>> 1 = 1 3/2 = 1 |
2.Java內置的進制轉換
十進制轉成十六進制 |
Integer.toHexString(int i) |
十進制轉成八進制 |
Integer.toOctalString(int i) |
十進制轉成二進制 |
Integer.toBinaryString(int i) |
十六進制轉成十進制 |
Integer.valueOf(“FFFF”,16).toString() |
八進制轉成十進制 |
Integer.valueOf(“376”,8).toString() |
二進制轉成十進制 |
Integer.valueOf(“0101”,2).toString() |
JDBC之“對岸的女孩看過來”
- JDBC簡介
JDBC全稱 Java Data Base Connectivity(java 數據庫連接)可以爲多種數據庫提供統一的訪問,體現了java “編寫一次,處處運行”的高大上精神。
- JDBC使用詳解
2.1 JDBC編程步驟
- 加載驅動程序:Class.forName(driverClass);
加載Mysql驅動:Class.forName(“com.mysql.jdbc.Driver”);
加載Oracle驅動:Class.forName(“oracle.jdbc.driver.OracleDriver”);
- 獲得數據庫連接:
DriverManager.getConnection(“jdbc:mysql://127.0.0.1:3306/imooc”,”root”,”root”);
- 創建Statement對象:conn.createStatement();
- JDBC各種連接方式的對比
- JDBC + ODBC橋的方式
特點:需要數據庫的ODBC驅動,僅適用於微軟的系統。
- JDBC + 廠商API的形式
特點:廠商API一般使用C編寫。
- JDBC + 廠商Database Connection Server + DataBase的形式
特點:在JAVA與DATABASE之間架起了一臺專門用於數據庫連接的服務器(一般由數據庫廠商提供)。
- JDBC + DATABASE的連接方式
特點:這使得Application與數據庫分開,開發者只需關心內部邏輯的實現而不需注重數據庫連接的具體實現。(推薦使用)
JDBC之“對岸的女孩走過來”
- JDBC詳解之存儲過程的調用
1.1 JDBC調用無參存儲過程
(1)存儲過程代碼:
CREATE PROCEDURE imooc_db.sp_select_nofillter()
BEGIN
Select * from imooc_goddess;
END;
- 調用代碼:
Connection conn = DBUtil.getConnection();
CallableStatement c = conn.prepareCall(“call sp_select_nofilter()”);
c.execute();
ResultSet rs = c.getResultSet();
1.2 JDBC調用帶輸入參數的存儲過程
- 存儲過程代碼:
CREATE DEFINER=’imooc’@’localhost’ PROCEDURE ‘sp_select_filter’(IN sp_name VARCHAR(20))
BEGIN
IF sp_name IS NULL OR sp_name = ‘’ THEN
SELECT * FROM imoo_goddess;
ELSE
IF length(sp_name)=11 AND substring(sp_name,1,1)=1 THEN
SELECT * FROM imooc_goddess WHERE mobile=sp_name;
ELSE
SELECT * FROM imooc_goddess WHERE user_name LIKE concat(‘%’,sp_name,’%’);
END IF;
END IF;
END
- 調用代碼:
//1.獲得連接
Connection conn = DBUtil.getConnection();
//2.獲得callablestatement
CallableStatement cs = conn.prepareCall(“call sp_select_filter(?)”);
cs.setString(1,sp_name);
//3.執行存儲過程
cs.execute();
//處理結果集:結果集,出參
ResutSet rs = cs.getResultSet();
1.3 JDBC調用帶輸出參數的存儲過程
- 存儲過程代碼:
CREATE DEFINER = ‘imooc’@’localhost’PROCEDURE ‘sp_select_count’(OUT count INT(10))
BEGIN
SELECT count(*) INTO count FROM imooc_goddess;
END
- 調用代碼:
//1.獲得連接
Connection conn = DBUtil.getConnection();
//2.獲得callablestatement
CallableStatement cs = conn.prepareCall(“call sp_select_count(?)”);
cs.registerOutParameter(1,Types.INTEGER);
//3.執行存儲過程
cs.execute();
//處理返回的記過:結果集,出參
cs.getInt(1);
- JDBC詳解之事務處理
2.1 事務的概念和特點
事務(TRANSACTION)是作爲單個邏輯工作單元執行的一系列操作。這些操作作爲一個整體向系統提交,要麼都執行、要麼都不執行。
- 原子性(Atomicity):事務是一個完整的操作。
- 一致性(Consistency):當事務完成時,數據必須處於一致狀態。
- 隔離性(Isolation):對數據進行修改的所有併發事務是彼此隔離的。
- 永久性(Durability):事務完成後,它對數據庫的修改被永久保持。
2.2 JDBC對事務管理的支持
- 我們通過提交commit()或是回退rollback()來管理事務的操作。
- 事務操作默認是自動提交。
- 可以通過調用setAutoCommit(false)來禁止自動提交。
- JDBC升級之連接池
3.1 常用的開源數據庫連接池
- dbcp
- c3p0
3.2 dbcp 與c3p0區別
dpcp |
C3p0 |
Spring組織推薦使用 |
Hibernate組織推薦使用 |
強制關閉連接或者數據庫重啓後,無法自動重連 |
強制關閉連接或者數據庫重啓後,可以自動重連。 |
沒有自動的去回收空閒連接的功能 |
自動回收空閒連接功能 |
DBCP有着比C3P0更高的效率,可能出現丟失連接。 |
C3P0穩定性較高 |
DBCP提供最大連接數 |
C3P0提供最大空閒時間 |
DBCP並沒有相應的功能 |
C3P0可以控制數據源內加載的PreparedStatements數量,並且可以設置幫助線程的數量來提升JDBC操作的速度。 |
- JDBC升級之替代產品
4.1 Hibernate簡介
優點:
- 輕量級的ORM框架。
- 對JDBC進行了很好的封裝,使用了ORM做了映射,那麼就可以通過面向對象的方式很容易的操作數據庫了。
- 它還提供了緩存機制,可以提高效率。
缺點:
如果對大量的數據庫進行頻繁的操作,性能效率比較低,不如直使用JDBC。
4.2 Hibernate核心接口
- Session接口:Session接口負責執行持久化對象的CRUD操作。
- SessionFactory接口:SessionFactory接口負責初始化Hibernate。它充當數據存儲源的代理,並負責創建Session對象。
- Configuration接口:Configuration接口負責配置啓動Hibernate,創建SessionFactory對象。
- Transaction接口:Transaction接口負責事務相關的操作。它是可選的,開發人員也可以設計編寫自己的底層事務處理代碼。
- Query和Criteria接口:Query和Criteria接口負責執行各種數據庫查詢。它可以使用HQL語言或SQL語句兩種表達方式。
4.3 MyBatis簡介
特點:
- 易於上手和掌握。
- sql寫在xml裏,便於統一管理和優化。
- 解除sql與程序代碼的耦合。
- 提供映射標籤,支持對象與數據庫的orm字段關係映射。
- 提供對象關係映射標籤,支持對象關係組建維護。
- 提供xml標籤,支持編寫動態sql。
Java高併發之魂:Synchronized深度解析
- Synchronized簡介
1.1 Synchronized的作用
能夠保證在同一時刻最多隻有一個線程執行該段代碼,以達到保證併發安全的效果。
1.2 Synchronized的兩個用法
(1)對象鎖:包括方法鎖(默認鎖對象爲this當前實例對象)和同步代碼塊鎖(自己指定鎖對象)。
其中同步代碼塊鎖示例:
/**
* 對象示例1,代碼塊形式
*/
public class SynchronizedObjectCodeBlock2 implements Runnable{
static SynchronizedObjectCodeBlock2 instance = new SynchronizedObjectCodeBlock2();
Object lock = new Object();
@Override
public void run() {
synchronized (lock){
System.out.println("我是對象鎖的代碼塊形式。我叫"
+Thread.currentThread().getName());
try {
Thread.sleep(3000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"執行結束");
}
}
public static void main(String args[]){
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()){
}
System.out.println("finished");
}
}
方法鎖示例:
/**
* 對象鎖實例2,方法鎖形式
*/
public class SynchronizeObjectMethod3 implements Runnable{
static SynchronizeObjectMethod3 instance = new SynchronizeObjectMethod3();
public static void main(String args[]){
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()){
}
System.out.println("finished");
}
@Override
public void run() {
method();
}
public synchronized void method(){
System.out.println("我的對象鎖的方法修飾符形式,我叫"
+Thread.currentThread().getName());
try {
Thread.sleep(3000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
(1)類鎖:指synchronized修飾靜態的方法或指定鎖爲Class對象。
類鎖概念:Java類可能有很多個對象,但只有一個Class對象。
只有一個Class對象:Java類可能會有很多個對象,但是隻有一個Class對象。
本質:所以所謂的類鎖,不過是Class對象的鎖而已。
用法和效果:類鎖只能在同一時刻被一個對象擁有。
類鎖兩種形式:
形式1:synchronized加在static方法上。
示例:
public static synchronized void method(){
System.out.println("我的對象鎖的方法修飾符形式,我叫"
+Thread.currentThread().getName());
try {
Thread.sleep(3000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
形式2:synchronized(*.class)代碼塊。
示例:
private void method(){
synchronized (SynchronizedClassClass5.class){
System.out.println("我是類鎖的第二種形式"+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("該線程執行關閉:"+Thread.currentThread().getName());
}
}
- 多線程訪問同步方法核心思想
- 一把鎖只能同時被一個線程獲取,沒有拿到鎖的線程必須等待(對應第1、 5中情況)
- 每個實例都對應有自己的一把鎖,不同實例之間互不影響;例外:鎖對象是*.class以及synchronized修飾的是static方法的時候,所有對象共用同一把類鎖(對應第2、 3、 4、 6種情況)。
- 無論是方法正常執行完畢或者方法拋出異常,都會釋放鎖(對應第7種情況)。
- Synchronized的性質
3.1 性質1:可重入
什麼是可重入:指的是同一線程的外層函數獲得鎖之後,內層函數可以直接再次獲取該鎖。
好處:避免死鎖、提升封裝性。
粒度:線程而非調用。
3.2 性質2:不可中斷
一旦這個鎖已經被別人獲得了,如果我還想獲得,我只能選擇等待或者阻塞,直到別的線程釋放這個鎖。如果別人永遠不釋放鎖,那麼我只能永遠地等待下去。
相比之下,未來會介紹的Lock類,可以擁有中斷的能力,第一點,如果我覺得我等的時間太長了,有權中斷現在已經獲取到鎖的線程的執行;第二點,如果我覺得我等待的時間太長了不想再等了,也可以退出。
- 深入原理
4.1 加鎖和釋放的原理
深入JVM看字節碼,使用javap -verbose *.class 來反編譯字節碼,使用monitorenter與monitorexit指令來進行加鎖與釋放鎖。
4.2 可重入原理:加鎖次數計數器
JVM負責跟蹤對象被加鎖的次數。
線程第一次給對象加鎖的時候,計數變爲1。每當這個相同的線程在此對象上在此獲得鎖時,計數會遞增。
每當任務離開時,計數遞減,當計數爲0的時候,鎖被完全釋放。
4.3 可見性原理:JAVA內存模型
4.4 Synchronized缺陷
- 效率低:鎖的釋放情況少、試圖獲得鎖時不能設定超時、不能中斷一個正在試圖獲得鎖的線程。
- 不夠靈活(讀寫鎖更靈活):加鎖和釋放鎖的時機單一,每個鎖僅有單一的條件(某個對象),可能是不夠的
- 無法知道是否成功獲取到鎖。
- 常見問題
- synchronized關鍵字使用注意點:鎖對象不能爲空、作用域不宜過大、避免死鎖。
- 有現成的包就用,如果適用優先使用synchronized關鍵字。
- 多線程訪問同步方法的七種具體情況
- 兩個線程訪問的是一個對象的同一個同步方法。
- 兩個線程訪問的是兩個實例的同一個同步方法。
- 兩個線程訪問的是synchronized的靜態方法。
- 同時訪問同步方法與非同步方法。
- 訪問同一個對象的不同的普通同步方法。
- 同時訪問靜態synchronized和非靜態synchronized方法
- 方法拋異常後,會釋放鎖。
JSP常用標籤
- JSTL簡介
JSTL是java中的一個定製標記庫集,它實現了JSP頁面中的代碼複用(基於標籤庫原理,重複率較高的代碼支持複用,提高效率),書寫JSP頁面時可讀性強。注意:JSTL標籤和Server及JSP頁面有着比較嚴格的版本對應關係,版本對應不正確很容易拋出異常。
環境搭建:新建web項目後將jar包導入,然後在使用的頁面上引入標籤庫:<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- EL表達式配合使用JSTL
- 什麼是EL表達式
全名爲:Expression language,經常與JSTL配合使用,使得JSP頁面更直觀,寫法更簡單。
普通寫法:<%=session.getValue("name") %>
EL表達式寫法:<c:out value="${sessionScope.name }"></c:out>
-
- EL表達式的格式
用美元符號”$”定界,內容包括在花括號”{}”中;${表達式}
- JSTL核心標籤的使用
- JSTL標籤之out標籤
- 輸出常量
可在value屬性中直接賦值
<c:out value=”this is our first JSTL demo”></c:out>
- 輸出變量
變量不存在時可配合default屬性輸出默認值,還可通過escapeXml控制轉移字符的輸出方式。
<%session.setAttribute(“name”,”Jessica”);%>
<c:out value=”${name}”></c:out>
-
- JSTL標籤之set標籤
存值到scope中:可將值以變量形式存放在指定的範圍中(2種形式)
<c:set value=”today” var=”day” scope=”session”></c:set>
<c:out value=”${day}”></c:out>
---------------------------------------未完,待續。。。。