面向對象的思想本質:以類的方式組織代碼,以對象的方式組織數據。java
JDK:java開發工具包,開發者用;程序員
JRE:運行時環境,運行Java程序只需jre就夠了;數據庫
JVM:java虛擬機。編程
三者關係:JDK 包含 JRE 包含 JVM。api
IDE:集成開發環境。數組
一個源文件能夠對應多個class文件;緩存
一個源文件中能夠有多個class,每一個class編譯時會對應生成一個class文件,該源文件中public修飾的class名必須和文件名同樣。安全
Java語言釋型仍是編譯型?仍是二者都是?網絡
編譯型語言:在程序運行以前,經過編譯,將源程序翻譯成機器語言,此後執行該程序就不用再進行翻譯了。app
解釋型語言:每次程序運行的時候,邊運行邊翻譯。
Java的運行過程:Java源文件(.java)經過Java編譯器(javac)編譯生成一個ByteCode字節碼文件(*.class),字節碼由Java本身設計的一個
計算機(即Java虛擬機,JVM)解釋執行,虛擬機將每一條要執行的字節碼送給解釋器,解釋器將其翻譯成特定的機器上的目標機器碼,而後在特定的機器上運行。Java的解釋器的優勢是比較容易讓用戶實現本身跨平臺的代碼,同一套代碼能夠在幾乎全部的操做系統上執行。
雖然Java的第一道工序是javac編譯,但其目標文件是ByteCode,而並不是機器語言,但後續可能有三種處理方式:
一、運行時,ByteCode由JVM逐條送給解釋器,解釋器將翻譯成機器碼運行。
二、運行時,部分ByteCode可能由實時編譯器(Just In Time Compiler,JIT)編譯爲目標機器碼再執行(以method爲翻譯單位,還會保存起來,第二次執行就不用再翻譯爲機器碼了),由於考慮到有些JVM是採用純JIT編譯方式實現的,其內部沒有解釋器,例如:JRockit、Maxine VM。
三、RTSJ,繼javac以後執行AOT二次編譯,生成靜態的目標平臺碼。
有的時候,多是以上三種方式同時在使用,至少,1和2是同時使用的,3則須要程序員手工指定。
我認爲java是編譯與解釋二者之間的混合式語言。
不少資料說,C/C++等是編譯型語言,而Java、C#、Python、JavaScript都是解釋型語言,是經過解釋器來實現的,其實這麼說很容易引發誤解:語言通常只會定義其抽象語義,而不會強制性要求採用某種實現方式,例如說C通常被認爲是編譯型語言,但C的解釋器也是存在的,例如Ch……因此通常被稱爲「解釋型語言」的是主流實現方式爲解釋器的語言,但並非說它就沒法編譯。
編譯時註釋跳過,字節碼文件中沒有註釋。
標識符不能以數字開頭;標識符不能包含除了字母、數字、下劃線、$以外的其餘字符。
Java內部採用Unicode字符集,能識別漢字。
字符集問題:
1.ISO8859-1:西歐字符集,1個字節;
2.GB2312:大陸使用最先、最廣的簡體中文字符集;
3.GBK:上者的擴展,能夠表示繁體中文;
4.GB18030:上者的擴展,能夠表示名族語言;
5.Unicode(UTF-8):國際通用字符集,2個字節;
byte:1字節;-128 ~ 127
short:2字節;-2的15次冪 ~ 2的15次冪-1(-32768~32767)
int:4字節;-2的31次冪 ~ 2的31次冪-1(正負21億,不用記)
long:8字節;-2的63次冪 ~ 2的63次冪-1(不用記),定義long類型變量時後面加「L」;
在Java中有兩個類BigInteger和BigDecimal分別表示大整數類和大浮點數類,理論上可以表示無線大的數,只要計算機內存足夠大;
這兩個類都在java.math.*包中;
float:4字節;浮點數有舍入偏差。定義float類型變量時後面加「F」;
double:8字節;浮點數有舍入偏差;
char:4字節;
科學記數法:「e」表示10的次冪;3.14e5 = 3.14*10的5次冪 = 314000
Java中八進制數以「0」開頭;十六進制數以「0x」開頭;
二進制:Binary
八進制:Octal
十六進制:Hex
運算符詳解:
關於取餘運算「%」:小數也能夠進行取餘運算。
關於移位運算符:
<<:左移運算:左移一次至關於乘以一個2;
>>:右移運算:右移一次至關於除以一個2;
如:
12<<2=48;12>>2=3;
math類:Math.random()——產生隨機數方法(隨機產生的是一個小於1的小數);
int e = (int)(Math.random() * 5);//隨機產生一個0-5之間的數;
switch語句注意:
1:每個case要加上一個break。
2:JDK7新特性:switch(a)中a能夠是字符串。
每行輸出定量個數後換行:
乘法口訣:System.out.peintln(i+"*"+m+"="+(i*m)+"\t");
API相關:
API:應用程序編程接口;
經過javaDOC生成api文檔;
生成API文檔專用註釋防範:/**
接收鍵盤輸入類:Scanner
自動類型轉換:容量小的數據類型能夠自動轉換爲容量大的數據類型。
特例:int類型數只要範圍不超過範圍比之小的byte、short、char,均可以直接轉換。
全部二元運算(+-*/···)都有類型提高的問題。
對象屬性默認值:
八種數據類型之外的任何默認值都爲null;
數字默認0;
bool默認false;
小數默認0.0;
內存分析:
棧:
1. 每一個線程私有,不能實現線程間的共享;
2. 局部變量放置於棧中;
3. 棧是由系統自動分配,速度快;
4. 棧是一個連續的內存空間;
堆(包含方法區):
1. 放置new出來的對象;
2. 堆是一個不連續的內存空間,分配靈活,速度慢;
方法區(也是堆):
1. 被全部線程共享;
2. 用來存放程序中永遠是不變或惟一的內容。(類的代碼信息、static靜態變量、字符串常量)
虛擬機內存管理垃圾回收機制:
程序員無權調用垃圾回收器;
程序員能夠經過system.gc()通知GC運行,可是並不能保證馬上運行;
finalize方法,是java提供給程序員用來釋放對象或資源的方法,不多用。
static詳解:
static變量從屬於類————存放在內存中的方法區,而new出來的對象發在堆區,從屬於對象。
因此在普通方法中能夠調用靜態方法和屬性,反之在靜態static方法中不能調用非靜態的屬性和方法。
this、super關鍵字詳解:都是隱式參數。
普通方法中:this老是指向調用該方法的對象;
構造方法中:this老是指向正要初始化的對象;
注意:this不能用於static方法。由於靜態方法不能調用非靜態的方法和屬性;
特殊用法:this(參數);//在一個構造方法中調用另外一個構造方法,可是必須在當前構造方法的第一行;
final關鍵字詳解:Cannot override the final method
修飾的變量不能再次被賦值;其修飾的方法不能被重寫,但能夠被重載;
其修飾的類不能被繼承(類中包括若干方法);
內部類詳解:
適用場景:只考慮爲其外部類提供服務;
每一個內部類能獨立實現接口或繼承類;
成員內部類:能夠無條件訪問外部類的全部成員屬性和成員方法(包括private)。當成員內部類的field或method與外部類相同時默認訪問的是內部類的。每一個實例都包含一個指向外圍實例的引用,若須要訪問外圍實例可以使用:外部類名.this.field/method。在外部類中訪問內部類的成員時須要先建立一個外部類,使用 .new語法。
Outter outter = new Outter();
Outter.Inner inner = new outter.new Inner();//必須經過Outter對象來建立
局部內部類:定義在一個方法內部或者是一段做用域內的類,僅限於在做用域內訪問;
靜態內部類:不依賴於外部類,不能用外部類的非static的域或者方法;
非靜態內部類必須寄存在一個外部類對象裏,非靜態內部類對象單獨屬於外部類的某個對象;
非靜態內部類可使用外部類的成員,可是外部類不能訪問非靜態內部類的成員;
內部類是 java的一顆語法糖,編譯以後會生成兩個 class 文件,匿名內部類名字爲:外部類名$x,成員內部類名字爲:外部類名$內部類名,編譯器會默認爲成員內部類添加一個參數類型爲指向外部類對象的構造方法。
好比咱們在一個方法內寫了一個 Thread 匿名內部類,當外部的方法執行完 畢後,方法內的局部變量生命週期結束,而 Thread 對象的生命週期尚未結束,因此必須使用 final 修改外部類的局部變量以使它在編譯階段就被放入常量池當中。
當咱們須要實例化一個成員內部類的時候,能夠經過 OuterClass.new InnerClass 的方式初始化;
若是咱們須要在內部類中生成對外部類對象的引用 可使用 OuterClassName.this。
數組詳解:
數組的本質仍是一個對象,操做數組就是操做指向該數組對象的引用;
String字符串:
一個String字符串自己屬性是final的,不能改變的,可是指向它的指針的屬性是能夠改變的——即當須要改變它的內容的時候會返回一個新對象;
eg: String str = new String("abc");
例子中字符串「abc」自己的屬性是不能改變的,可是其指針str是能夠改變的。
String對 + 運算符的重載其實是使用StringBuilder.append()建立了一個新的String對象;
String 爲何設計成不可變對象?
源碼分析:
public final class String // 不能被繼承
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
包含兩個成員變量:value:String 的字符序列;hash:該 String 對象 hash 值 的緩存。咱們經過普通代碼對一個 String 的改變都是經過返回一個新的 String 對 象來完成的。可是 String 也不是絕對不可變的,咱們能夠經過反射拿到 value 對 象,而後改變它。 (final 域是不能修改的,可是若是 final 域指向的對象是可變的, 咱們就能夠修改 final 域指向對象的內容)
設計成不可變對象的好處:
1. 由於它是不可變的,因此其 hashCode()永遠保持一致,也就是每次在使 用一個 String 對象的 hashCode 的時候都不用從新計算,直接返回 hash 值便可,效率更高;
2. 不可變對象天生線程安全,能夠無需同步的在多個線程間共享;
3. 安全性,經常使用於數據庫鏈接、網絡鏈接、打開文件等,避免了參數修改。
StringBuilder可變字符串,線程不太安全,但效率高,推薦使用;
StringBuffer可變字符串,線程安全,但效率低,不推薦使用;
三者執行速度上:StringBuilder > StringBuffer > String
Integer緩存處理詳解:
[-128,127]之間的數,仍然看成基本數據類型(比對象的處理速度快)來處理;
eg:若int a=1234;int b=1234;則代碼a==b與a.equals(b)的結果不一樣:
"==":比較的是指向該變量的地址;——return false;
equals函數:比較的是兩個變量的值;——return true;
若上例中a和b處於[-128,127]之間,則"=="和equals均返回true;
集合與容器Collection詳解:
1.集合只能存放對象。好比你存一個 int 型數據 1放入集合中,其實它是自動轉換成 Integer 類後存入的,Java中每一種基本類型都有對應的引用類型;
2.集合存放的是對各對象的引用,對象背身仍是放在對內存中;
3.集合能夠存放不一樣類型,不限數量的數據類型;
迭代器/遊標iterator:
爲容器遍歷而生——提供遍歷容器對象中各個元素的方法;相似於公交車上的售票員——關注公交車上的每一個乘客;
一般分爲三個步驟:獲取迭代器對象、先檢查、再獲取;
ArrayList<String> list = new ArrayList<String>();
list.add(「馬雲」);
list.add(「馬化騰」);
//一、根據容器獲取迭代器對象
Iterator<String> it = list.iterator();
//二、檢查是否 存在下一個元素
while( it.hasNext() ){
//三、內部移動遊標,獲取元素
String element=it.next();
//…其餘處理
}
容器相關詳解:
ArrayList底層實現是數組,查詢快,增刪慢;線程不安全效率高;
LinkedList底層實現是鏈表,查詢慢,增刪快;線程不安全效率高;
Vector線程安全,效率低;
HashMap:鍵值對(key-value)詳解:
經過對象來對對象進行索引,用來索引的對象叫作key,其對應的對象叫作value