文章目錄
類的四種加載
Object obj = new Object();
引用變量信息保存在 虛擬棧
對象實例數據保存在 堆區(GC新生代區),
對象類型數據(接口,方法,版本,靜態成員等)保存在 方法區
指向對象實例數據的指針在 句柄池
指向對象類型數據的指針在 句柄池
句柄池在堆區
類加載器會先加載方法區,即將靜態成員裝載到方法區內,變相創建對象,並且方法區只能被裝載一次.
程序計數器:當前線程執行到的代碼行
本地方法棧:運行C之類的native方法
## 內部類助外部類實現多繼承
內部類可以繼承一個與外部類無關的類,並在外部類中,供外部類使用內部類對象的相關方法,變相實現多繼承
如兒子同時繼承父母親的特特色(功能)
interface Father{ public int strong();}
interface Mother{ public int kindHeart();}
class FatherImpl extends
OOP
抽象,繼承,封裝,多態
抽象
就是把現實世界中的某一類東西按一定的邊界提取出來.系統需要什麼就抽象什麼,多餘的統統不考慮
數據屬性抽象,過程行爲抽象
封裝
封裝使得軟件能模塊化開發,特點是高內聚,低耦合,設計模式.
最典型的封裝就是對象,將對象內的屬性私有化,只供對象內部方法調用,對外公開方法,供人調用.注意要把對同一類事物的操作與相關屬性數據放到同一個類中.
繼承
在一個已經存在的類的基礎上,加入若干新內容,或修改原來的方法使之更適合特殊需要.
特點,子類之間可以自動共享父類的數據和方法.該機制提高了軟件的可重用型和可拓展性
多態
客戶端源碼中有這樣一句
Father son1 = new Son1();//Son1繼承父類show1方法,自定義show2方法
編譯器器不會制定son1這個引用到底指向哪個類型
運行
son1.show1();
運行方法時才確定son1這個引用對象調用的是Son1類裏繼承的父類方法
原理:動態綁定
- 編譯時看的是引用的聲明,像Father1 father1 = new Son1();編譯器只會知道father1的聲明類型是Father1,找方法也在Father1中找.
- 所以Father1中有show1方法,故father1.show1()調用成功,但是Father1中沒有show2方法,故father1.show2()編譯出錯。
- 至於father1.show1()最終調用的是子類的show1方法,則就是動態綁定的問題。
- 動態綁定:運行時自動確定調用哪個方法的現象。
動態綁定調用的全過程: - 編譯器查看對象的創建類型和調用的方法名,然後一一列舉出聲明類型和該類型的超類中同方法名的所有方法(超類中的需要是public屬性的);
- 根據調用方法的參數,選擇合適的一個函數(合適指的是類型完全相同或者自動轉換類型後符合)。如果沒找到那麼直接報錯。
- 虛擬機確定對象的實際類型,尋找該類型下的合適方法調用,如果沒找到則到超類中去找。
-靜態綁定(如果方法爲private,final,static則採用靜態綁定,編譯時已經索引好具體調用的地址)
數據類型
8+1+1 八種基本+枚舉+引用
抽象類
非抽象類繼承一個抽象類,必須覆蓋父類所有抽象方法
abstract 不可private、static、final、native
從final講繼承
繼承類意味着子類會有改動,不然繼承個屁
繼承時繼承方法卻不意味會改動它,因爲改動它叫覆蓋
- 就近原則 final 修飾的變量不可變引用,引用對象還是可變的
- 所以final類不可修改,不可繼承
- 普通類中final方法可以繼承,不可覆蓋
- final 不可修飾abstract
- final可以重載,因爲重載不與它衝突(重載並沒有說誰在誰的基礎上改動生成新方法).它歡迎被人使用,但不可修改
JSP與Servet,視圖與控制
- Servlet 完全是 JAVA程序代碼構成,擅長於流程控制和事務處理,通過Servlet 來生成動態網 頁很不直觀.
- JSP 由 HTML 代碼和 JSP 標籤構成的.jsp文件,可以方便地編寫動態網頁.
- 因此在實際應用中採用 Servlet 來控制業務流程,而採用 JSP(簡易Servet) 來生成動態網頁.
- JSP嵌入JAVA代碼,Servet嵌入HTML代碼
static靜態
靜態成員屬於類,只要程序加載了類的字節碼,靜態成員就會被分配空間,可以直接調用
- 靜態代碼塊內部不可訪問非靜態成員,因爲類加載時,無法確定非靜態成員的內容(尚未實例化)
- 非static成員當然可以訪問static成員
== 與 equals的區別
- == 判斷基本數據類型的話,用於判斷內容或大小是否相等
- == 判斷引用對象時,判斷內存地址是否相同
- 即==用於判斷二者是否同一個對象
- equals相對不會這麼嚴格,只要內容相等就返回True
- 順便一提Integer是引用,默認爲null
public等作用域
- public 不管是不是同一個包內都可以訪問到
- protected 同一包內可以訪問,不在同一個包內的,必須繼承後再共享裏面的數據與屬性,這是一種對父類的保護,保證每個子類繼承的父類數據是一樣的.
- default 同一個包內的類,接口可以互相訪問
- private 僅同一類內可以訪問
接口與抽象的區別
- interface 內成員必須是public,抽象類可以有private
- interface內不可有普通方法,抽象類可以有
- 二者都不能new,不是普通類.二者常用語設計模式和代碼重構
final,finally,finalize
- final是聲明式關鍵字,用它聲明的成員有以下效果.final屬性不可修改(常量),final方法可繼承不可覆蓋,final類不可繼承
- 局部內部類要訪問局部變量,局部變量必須定義成final類,引用始終指向該變量.內部類可訪問外部類成員
- finally 異常語句,表示無論catch了什麼,最終都要執行
- finalize,Object類的垃圾回收方法GC時會用到
String,StringBuilder,StringBuffer
- String爲字符串常量,而StringBuilder和StringBuffer均爲字符串變量,即String對象一旦創建之後該對象是不可更改的,但後兩者的對象是變量,是可以更改的。
- String str;是字符串常量,屬於不可變對象. str只能賦值一次,第二次賦值原理的對象str會被GC回收,JVM新建一個str.於是大量操作的時候,不斷回收與創建會使程序運行緩慢,效率低下.
- StringBuilder與StringBuffer都是字符串變量,屬於可變對象.
- StringBuilder線程不安全,StringBuffer線程安全.
StringBuilder stringBuilder=new StringBuilder().append(“abc”);
stringBuilder = stringBuilder.append(“de”);
OBject類方法
- clone方法
- getClass方法 ,獲取運行時的類型
- toString方法 打印對象名,對於調用該對象的toString方法
- finalize 釋放資源,很少使用
- equals方法,在Object的源碼中equals返回的是
public boolean equals(Object obj){
this == obj;
}
length屬性與length方法
- Array.length,String.length()
hashCode() collections常用
- Set集合不允許有重複元素.
- 看某個對象是否已經在一個對象集合內,先用hashCode()快速對比,再在hashCode()爲True的對象裏,用equals找內容相等的對象,若都找不到,則說明該集合內,並沒有與該對象重複的對象.
線程
線程構造器必須傳入一個實現了Runnable接口的類的對象,以此創建類線程對象
public Study implements Runable(){}
Thread thread = new Thread(new Study())
- 等待獲取鎖 : wait(long timeout)
- notify,notifyAll,interrupt,wait時間到
反射
我們可以通過反射動態讀取正在運行的類的元數據
- 優點靈活,可拓展,實現正在運行的類可配置
- 缺點是解釋操作,字段接入的速度非常慢.
- 用處:jdbc,java框架,jdk動態代理
流操作
- 字節流繼承於:InputStream,OutputStream
- 字符流繼承於:InputStreamReader,OutputStreamWriter
- 當然在java.io包裏還有更多其他流操作,需要的時候查一下JDK文檔即可
多線程
本質,在同一個進程中,有多個不同的執行路徑
- 充分利用系統資源,縮短程序響應時間
- 進程是線程的集合
- 線程同步,線程都在同一個路徑內,前一個線程執行完畢後,下一個線程再接着執行
- 線程異步,進程中有多個不同的執行路徑
- 線程間強行同步,synchronized,wait,notify
線程安全
- 同步是線程安全的
- 假設種樹這個任務有三個線程:挖坑線程,種樹線程和填坑線程,後面的線程(上鎖)必須等前一個線程完成才能進行,而不是按時間順序來進行.
- 否則按時間執行的話,就會出現一旦某個線程出問題未響應,時間自動執行下一個線程,極大概率出現數據不存在,對象不存在,或內存泄漏的問題
- 根據同步實現線程安全:synchronized,wait都是所後面的線程,前一個線程完成後纔會執行後一個線程
- 根據不可修改實現線程安全:final,Lock
創建線程
- 繼承Thread類,自己實現run方法, new 一個對象後,調用對象的start方法
- 寫一個目標類實現Runable接口,實現run方法,new一個目標類對象後,將該對象傳入Thread類的構造方法中,啓用Thread對象的start方法
- 推薦實現Runable接口,因爲這樣可以再繼承別的類,而繼承Thread類只能是單繼承.我們都知道,Java是隻允許單繼承的,我們一定要繼承Thread類的話,可以用內部類,間接實現多繼承
爲什麼要實現Serializable接口
一個對象序列化的接口,一個類只有實現了Serializable接口,它的對象才能被序列化
內部類
類中類實現多繼承
- 內部類的構造方法挪到外部類,就是外部類的普通方法
class A{
void output(){}
class B{
void output(){}
}
B newB(){
B b = new B();
return b
}
void main(){
}
}