瘋狂Java摘要
1.語言零碎基礎知識
<1>.Windows中系統(tǒng)變量有系統(tǒng)變量和用戶變量之分篙顺,就是作用域大小的區(qū)別
<2>.Ruby:弱類型德玫,最大的特點就是簡潔。Python:語言簡潔語法清晰
<3>.每一個函數(shù)方法都有一個方法棧
<4>.看待每一個對象都可以分為兩部分材彪,一部分在棧區(qū)琴儿,一部分在堆區(qū)
<5>.方法復寫時要注意“兩小一大”原則
- a.子類方法返回值類型要小于等于父類
- b.類方法要么不拋出異常造成,要么拋出父類異成故海或者子類。
- c.子類方法的訪問權限要大于等于父類
<6>.子類同名實例變量不會覆蓋父類的蕴轨,只是簡單的隱藏了父類的實例變量
<7>.instanceOf()
判斷的是前面對象是否是后邊類或者后邊類的子類的實例骇吭。t.getClass() == Person.class
則不包含子類
<8>.繼承和組合:前者會開辟兩份父類變量的內(nèi)存空間;后者子類和父類對象內(nèi)存空間各一份成福,只需要多一個引用變量。這就是著名的is-a和has-a關系
<9>.工廠設計模式建議一個A類組合B類時最好面向接口净当,將A類和B類完全分離像啼,建立B對象的邏輯交給工廠,當對B類進行擴展時完全不影響A類
<10>.Java8新特性:接口中允許添加默認方法真朗,默認方法可以提供方法實現(xiàn)
<11>.Java8新特性:局部內(nèi)部類訪問局部變量時不用我們用final修飾遮婶,其實這個變量會默認被final修飾湖笨,所以同樣我我們不能多次對她賦值
<12>.Java8新特性:Lambda表達式允許使用簡潔代碼創(chuàng)建只有一個方法的接口實例對象慈省,省略了要復寫方法名與修飾符和new對象的語句边败。使用簡寫規(guī)則如下:
- a.允許省略形參的類型,如果形參列表只有一個參數(shù)致燥,那么小括號也能省略篡悟。
- b.代碼塊中只有一條語句匾寝,可以省略代碼塊的大括號艳悔。如果這僅有的一條語句還是返回語句,那么return也能省略
- c.不帶形參的直接寫對小螺號即可抡锈。
<13>.直接量賦值字符串變量床三,常量池會緩存字符串直接量撇簿。
String srr1 = "霧雨魔理沙";
String str2 = "霧雨魔理沙";
String str3 = "霧雨"+"魔理沙";
str1 == str2 == str3;
<14>.大類型強轉(zhuǎn)為小類型可能會造成信息丟失(long --> int 會丟失前32位的數(shù)據(jù))
<15>.不常用關鍵字:assert
、goto
汉嗽、transient
饼暑、stictfp
弓叛、volatitle
竭望、const
<16>.Jar:Java Archive File(Java檔案文件)
<17>.Obejct對象的clone()
方法:這是淺層的克隆咬清,此克隆方法只克隆該對象所有成員變量值旧烧,不會對引用數(shù)據(jù)類型成員變量引用的對象進行克隆
<18>.Java7特性:新增了ThreadLocalRandom,相比Random可以減少多線程資源競爭平委,最終保證系統(tǒng)具有良好的線程安全廉赔,功能與使用與過去的Random相同
<19>.Random使用注意:Random對象本身使用一個48位的種子創(chuàng)建匾鸥,對她們一同樣的順序調(diào)用方法勿负,則她們產(chǎn)生相同的數(shù)字序列
<20>.在Java中如果對浮點數(shù)進行算術運算時不可直接計算,結(jié)果會發(fā)生精度丟失铁孵,可以把浮點數(shù)封裝到BigDecimal中進行計算房资,封裝時不可使用構造函數(shù)new BigDecimal(double d)
志膀,可以使用new BigDecimal(String s)
或者BigDecimal.valueOf(double d)
來封裝浮點數(shù)溉浙,再進行計算蒋荚,或者計算浮點數(shù)的方法用 Strictfp
關鍵字來修飾
<21>.Calendar對象的set()
方法有延遲修改的特性期升,除非你調(diào)用get()播赁、getTime()、getTimeMillis乓序、add()替劈、roll()是才會重新計算日歷的時間陨献,把特殊的時間修正正確懂更,如8月31日你修改成9月31日沮协。
2.垃圾回收機制篇
<1>.優(yōu)點:如果沒有此機制皂股,無論是忘記回收還是錯誤的回收都會導致系統(tǒng)的崩潰
<2>.缺點:機制的開銷影響程序的性能
<3>.特點:
- a.只能回收內(nèi)存資源,對物理資源無力
- b.讓對象引用指向null就斤,只是暗示回收機制回收此對象
- c.Runtime()和System.gc()回收開啟僅僅是建議系統(tǒng)這樣做洋机。
<4>.垃圾回收機制只負責回收推內(nèi)存中的對象绷旗,回收對象之前,總會調(diào)用它的finalize()
方法庄岖,該方法可能讓對象重新復活隅忿,從而取消垃圾回收機制
<5>.流程:對象被回收時分為三個狀態(tài):
- a.可達狀態(tài)背桐,一般狀態(tài)蝉揍,不可被回收
-
b.可恢復狀態(tài)又沾,對象沒有被引用捍掺,并且
finalize()
方法未被調(diào)用 - c.不可達狀態(tài)挺勿,徹底失去引用,會被垃圾回收機制回收
<6>.可通過Runtime.getRuntime().runFinalization()
或者System.runFinalization()
強制垃圾回收機制調(diào)用對象的finalize()方法禾嫉,不過這之前要先調(diào)用System.gc()
或者Runtime.getRuntime().gc()
來開啟gc()才可以熙参。
//可用如上這種寫法保證單例對象永遠不為空(待測試)
class NewInstance{
private static NewInstance instance = new NewInstance();
private NewInstance(){}
public static NewInstance getInstance(){
return instance;
}
public void finalize(){
instance = this;
/*
System.gc();
System.runFinalization();可用這兩個方法強制調(diào)用對象的finalize()方法
*/
}
}
<7>.4中常見引用
- 強引用:我們一般定義的引用都是強引用
- 軟引用:通過SoftReference類來實現(xiàn)孽椰,一個對象只有軟引用時,系統(tǒng)內(nèi)存空間足夠時不會被回收栏渺,當系統(tǒng)空間不足時可能會被回收
- 弱引用:通過WeakReference類來實現(xiàn)磕诊,比軟引用還弱的引用纹腌,一個對象只有弱引用時升薯,不管系統(tǒng)內(nèi)存空間是否足夠都有可能被回收
- 虛引用:通過PhantomReference類來實現(xiàn)覆劈,如果一個對象只有一個虛引用時那么它和沒有引用效果大致相同责语。虛引用主要用于跟蹤垃圾回收的狀態(tài)目派,虛引用不能單獨使用企蹭,必須與引用隊列ReferenceQueue聯(lián)合使用谅摄。
代碼:
軟引用或者弱引用的使用方法:
WeakReference weakRef = new WeakReference(new String("弱引用"));
weakRef.get();//返回值為字符串送漠,不會導致內(nèi)存緊張的情況下其實這里一般不會回收
System.gc();
System.runFinalization();
weakRef.get();//返回值可能為null,垃圾回收機制回收了引用
虛引用的使用方法:
ReferenceQueue queue = new ReferenceQueue();//引用隊列
PhantomReference phantomRef = new PhantomReference(new String("虛引用"),queue);
phantomRef.get();//返回值為null代兵,不能獲取虛引用的引用對象
Runtime runtime = Runtime.getRuntime;
runtime.gc();
runtime.runFinalization();
queue.poll() == phantomeRef;//比較結(jié)果為true植影。垃圾回收完思币,引用存放在了引用隊列中谷饿,取出最先進入隊列的引用
3.集合框架
<1>.Java8新特性:Iterable接口添加了void forEach(Consumer action)
方法各墨,Collection體系也從而有了這個方法,Consumer是一個函數(shù)式接口恃轩。foreach()方法會把集合元素傳遞給Comsumer處理叉跛。所以可以寫成如下形式:
list.forEach(obj -> System.out.println("方法1筷厘,迭代的集合元素是:"+ obj);
<2>.Java8新特性:通過Iterator接口的默認方法void forEachRemaining(Consumer action)
forEachRemaining(obj -> System.out.println("方法2酥艳,迭代的集合元素是"+obj))
<3>.Collection集合新增removeIf(Predicate fileter)
方法充石,將符合fileter條件的元素全部刪除霞玄,Predicate也是一個函數(shù)式接口坷剧,可寫成如下形式
list.remove(filter -> ((String)fileter).length() > 5)
注:Predicate有一個test(Object o)方法惫企,可以檢測數(shù)據(jù)是否符合自己的規(guī)則雅任,規(guī)則通過復寫接口的抽象方法傳遞。
<4>.Colleation接口新增默認方法sream()獲取操作該集合的流式對象硼婿,集合通過流式API處理集合.
流式API有Stream寇漫、IntStream州胳、LongStream栓撞、DoubleStream
等常用瓤湘,這種流式操作分為中間方法和末端方法,中間方法一般會返回一個流挽懦;末端方法是流的最終操作信柿,只能執(zhí)行一次這種方法渔嚷。具體流式方法可去查詢API并且練習使用
<5>.EnumSet類圃伶,是一個專門為枚舉設計的集合類,線程不同步蝗岖,集合元素是有序的抵赢,排序方式通過枚舉值在集合內(nèi)的定義順序作為集合元素的順序铅鲤。內(nèi)部以位向量形式存儲邢享,非常緊湊高效骇塘,占用內(nèi)存小款违,運行效率好,不可插入null
<6>.Arrays.asList(Object... o)
返回的list不是ArrayList的實現(xiàn)類哄辣,而是Arrays的內(nèi)部類ArrayList的實例力穗,這是一個固定長度的List集合睛廊,只能遍歷超全,不能增刪嘶朱。
<7>.TreeMap 的排序作用的Map中的Key疏遏,與value無關财异。
<8>.一個Map的key值為null唱遭,其實這就是一個Set集合
<9>.WeakHashMap 的 key只保留實際引用的弱引用拷泽,垃圾回收可能回收鍵值司致。前提是該key所引用的對象不被任何強引用引用脂矫,如果key的值是字符串羹唠,那么定義為【"java"】這種形式,其實"java"直接量已經(jīng)被系統(tǒng)強引用
<10>.IdentityHashMap 基本與HashMap一樣萌焰,不過當她判斷兩個key是否相等時扒俯,當且僅當key1==key2時撼玄,IdentityHashMap才認為兩個key相同
<11>.**EnumMap **內(nèi)部以數(shù)組形式保存掌猛,實現(xiàn)形式非常緊湊荔茬、高效慕蔚。根據(jù)Key的自然順序(枚舉值得定義先后順序)進行的排序
<12>.Collections 有多個synchronizedXxx()
方法來同步集合斋配,并且可以通過unmodifiableXxx()艰争、emptyXxx()甩卓、singletonXxx()
獲取一個不可變集合猛频,修改此集合會拋出UnsupportedOperationException()
<13>.Queue集合鹿寻,模擬隊列的數(shù)據(jù)結(jié)構毡熏。有3個添加的方法痢法,3個取出的方法狱窘,和2個查詢隊頭元素的方法
- a.PriorityQueue,隊列實現(xiàn)類,按照隊列元素的大小順序進行排序的隊列财搁,取出時取出的是最小元素蘸炸。當熱也可以通過Comparable定制排序規(guī)則
- b.Deque接口是Queue的子接口,這是一個雙端隊列尖奔,可以從兩端任意一段存或取數(shù)據(jù)的集合
- c.ArrayDeque基于數(shù)據(jù)的雙端隊列搭儒,指定隊列長度提茁,如果不指定隊列默認長度為16淹禾。當程序需要使用棧這種數(shù)據(jù)結(jié)構時推薦使用此對象
<14>.注意:
- a.底層數(shù)組隨機訪問性能會很好,鏈表結(jié)構插入和刪除性能很好茴扁×宀恚總體來說ArrayList性能優(yōu)于LinkedList,優(yōu)先考慮ArrayList
- b.遍歷集合時數(shù)組數(shù)據(jù)結(jié)構的采用隨機訪問形式遍歷集合(get(index))峭火,對于鏈表結(jié)構使用迭代器的方式
- c.如果有多個線程訪問集合毁习,開發(fā)者考慮到線程安全,可以使用Collections將集合包裝成線程安全的集合
4.泛型
<1>.Java7支持菱形語法躲胳,不需要帶完整的泛型信息蜓洪,只有給出一対<>尖括號即可。
<2>.2.父類定義了泛型坯苹,子類繼承父類隆檀,父類要么不能包含類型形參,要傳入實際參數(shù)粹湃;或者包含類型形參恐仑,不過子類也要包含類型形參。如下兩種寫法
class GenericSon extends GenericSon<String>{}
class GenericSon<T> extends GenericSon<T>{}
3.Person<String>不是Person<Object>的子類为鳄,所以不能使用多態(tài)形式接收裳仆。想用多態(tài)可以寫成Person<? extends Object> p = new Person<String>();
或者Person<?> p = new Person<String>();
4.Object[] arr = new String[];
這種寫法編譯能通過,不過就算能通過也不要這樣表示孤钦,沒有意義
5.泛型的上限可通過【&】符號指定多個且的關系歧斟,如:class Apple<T extends Number & Serializable>
6.泛型方法其實就是在方法簽名處定義方法泛型供整個方法使用
7.按理說只要是使用通配符的地方同樣也能寫成泛型方法,如果方法多個參數(shù)之間類型有依賴關系或返回值與參數(shù)之間的依賴關系應該使用泛型方法偏形;如果沒有這種依賴關系静袖,則可以使用通配符【?
】
9.泛型有擦除的特性,如下語句不會報錯俊扭,能夠正常運行队橙。當執(zhí)行第三局時list集合的泛型類型Integer已經(jīng)被擦除,這樣做集合不能獲取元素會發(fā)成ClassCastException,不過能存入元素
List<Integer> list = new ArrayList<Integer>();
list.add(1);
List objList = list;
List<String> stringList = objList;
stringList.add("帕秋莉·諾蕾姬");
5.異常相關
<1>.Java7特性:支持多異常捕獲捐康,一個catch可以處理多個異常仇矾,寫法如下:并且注意這個異常變量是被final修飾,一般單異常處理的catch不用final修飾
catch(IndexOutOfBoundsException | NumberFormatException e){}
<2>.Java7特性:自動關閉資源的try語句解总,不過這些資源需要實現(xiàn)AutoCloseable或Closeable接口贮匕,我們不用寫關閉資源的語句,自動關閉資源倾鲫。Java 7重寫了所有資源類
try(FileReader fr = new FileReader(path);FileWriter fw = new FileWriter(path)){
//方法體粗合,并且fr和fw這兩個流在代碼運行完畢或者異常錯誤后都會自動關閉
}catch(IOException e){}
<3>.異常鏈:把原始異常異常信息隱藏起來,僅向上提供必要的異常提示信息的處理方式乌昔,可以保證底層異常不會擴散到表現(xiàn)層隙疚,符合面向?qū)ο蟮姆庋b設計。實現(xiàn)就是捕獲一個異常然后拋出另一個異常磕道。----責任鏈設計模式
public void calsal() throws SalException{
try{
//義務邏輯
}catch(SQLException e){
//把原始異常記錄下來供屉,留給管理員
throw new SalException("訪問底層數(shù)據(jù)庫出現(xiàn)異常");
}
}
<4>.Java的異常跟蹤棧,大多數(shù)復雜的操作都會被分解成一系列方法調(diào)用溺蕉。異常打印一般都是把跟蹤棧中的異常全部打印出來伶丐,保持跟蹤棧的不斷通過 throw new RuntimeException(e)即可》杼兀看異常信息一點一點的看哗魂,結(jié)構是————【at 類名.方法名(Java文件名.java:行數(shù))】
<5>.異常避免過度使用,正常的業(yè)務邏輯不要使用異常漓雅。Catch All語句不過是一種避免錯誤處理而加快變成進度的機制录别,應避免在實際應用中使用這種語句———— catch(Throwable e){}
6.IO流相關
<1>.不常用IO流:AudioInputStream 、 CipherInputStream 邻吞、 DeflaterInputStream 组题、 ZipInputStream
等,訪問音頻文件 / 加密 / 解密 / 壓縮 / 解壓功能的流
<2>.Java虛擬機可讀取其他進程的數(shù)據(jù)抱冷,通過Runtime.exec("程序名")
來獲取Process進程對象崔列,然后可獲取子進程流對象
InputStream getErrorStream();獲取子進程的錯誤流
InputStream getInputStream();獲取子進程的輸入流
InputStream getOutputStream();獲取子進程的輸出流
<3>.對象序列化步驟:
- a.序列化對象實現(xiàn) Serializable 接口或者 Externalizable 接口
- b.通過 ObjectOutputStream 來把對象序列化到本地;通過 ObjectInputStream 來讀取序列化到本地的對象
注意:
- a.如果序列化對象成員有引用數(shù)據(jù)類型的變量旺遮,那么這個引用的對象也要是能序列化的赵讯,否則該對象不能進行序列化操作。
- b.每一個序列化的對象都有一個序列化編號耿眉,如果該對象序列化過瘦癌,那么程序不會再次序列化該對象,而是直接引用這個序列化編號
- c.由于這個引用現(xiàn)象的出現(xiàn)跷敬,所以序列化可變對象時,序列化的對象數(shù)據(jù)是第一次writeObject()的數(shù)據(jù),之后改變數(shù)據(jù)寫入多少遍該序列化的數(shù)據(jù)都是第一次的數(shù)據(jù)
- d.使用關鍵字 transient 修飾的成員西傀,可以在序列化時無視這個成員
- e.可以自定義序列化邏輯
<4>.Java 1.4新增NIO概念斤寇,非常重要,非阻塞式IO流拥褂,以后一定要看一下娘锁。并且在Java 1.7中新增NIO2的感念,有遞歸目錄的簡易方法饺鹃,一定要看一下莫秆。
<5>.Charset類,字符集Charset相關API
static charset forName(String str); 獲取字符集對象
CharsetEncoder newEncoder(); 返貨字符編碼器,通過encode(CharBuffer buf)編碼字符
CharsetDecoder newDecoder(); 返回字符解碼器悔详,通過decode(ByteBuffer buf)解碼字節(jié)
CharBuffer decode(ByteBuffer bb); 解碼字節(jié)
ByteBuffer encode(CharBuffer cb); 編碼字符
ByteBuffer encode(String str); 編碼字符串镊屎,與String類的getBytes(String str)一樣
<6>.文件鎖,可以有效阻止多個進程并發(fā)修改同一個文件茄螃。大部分系統(tǒng)都提供了文件鎖的功能缝驳。使用: FileChannel
中提供了lock()/tryLock()
來對文件添加文件鎖并且獲取到 FileLock
對象。再通過 FileLock
對象的release()
方法釋放鎖
特點:
-
a.
lock()
是阻塞式方法归苍,獲取不到文件鎖對象將阻塞 -
b.
tryLock()
只是嘗試鎖定文件用狱,鎖定文件將返回鎖,否則返回null -
c.還有
lock(long position,long size,boolean shared)
和tyrLock(long position,long size,boolean shared)
拼弃。position是加鎖內(nèi)容開始的位置夏伊;size是加鎖內(nèi)容的長度;shared表示該鎖是共享鎖還是排他鎖
示例代碼:
class FileLockTest
{
public static void main(String[] args)throws Exception{
try(
FileChannel channel = new FileOutputStream("a.txt").getChannel()
){
//10s中只有主線程能對a.txt文件進行修改
FileLock lock = channel.tryLock();
Thread.sleep(1000);
lock.release();
}
}
}
7.線程相關
<1>.并行性(Parallel):指的是同一時刻吻氧,有多條指令在多個處理器上同時執(zhí)行溺忧。并發(fā)性(Concurrency):指在同一時刻只有一條指令執(zhí)行,但多個進程指令快速切換執(zhí)行医男。
<2>.程序只是一個靜態(tài)的指令集合砸狞,而進程是一個正在系統(tǒng)中活動的指令集合。
<3>.使用Callable和future創(chuàng)建線程的方式镀梭。特點刀森,能獲取到線程方法執(zhí)行完畢后的返回值。執(zhí)行過程中獲取返回值會造成線程阻塞报账。Future的實現(xiàn)類 FutureTask 有一些方法來獲取返回值
class CallableThread
{
public static void main(String[] args){
//使用Lamada表達式來創(chuàng)建一個Callable對象
Callable<Integer> callable = (Callable<Integer>)()->{
//Callable中call方法的邏輯研底,就是線程的邏輯。有返回值
...
return i;
}
//創(chuàng)建Future對象來操作這個callable對象
FutureTask<Integer> futureTast = new FutureTask<Integer>(callable);
Thread.sleep(1000);
new Thread(futureTest,"Callable創(chuàng)建線程").start();
Thread.sleep(2000);
//通過get()返回子線程返回值透罢,此方法在線程未執(zhí)行完畢時調(diào)用會阻塞住線程
System.out.println("子線程返回值"+futrueTask.get());
}
}
<4>.線程狀態(tài):被創(chuàng)建榜晦,就緒,運行羽圃,阻塞乾胶,消亡。(這里自己過去理解有很大誤區(qū)!识窿!)
(1)線程被阻塞有如下幾種情況:
-
a.線程被
sleep()
或者jion()
; - b.調(diào)用了阻塞式IO方法
- c.同步監(jiān)視器正被其他線程持有
- d.線程在等待某一個通知,被wait()了
-
e.程序調(diào)用了線程的
suspend()
方法將該線程掛起(容易造成死鎖斩郎,盡量避免使用)
(2)被阻塞的線程解除阻塞后會恢復到就緒狀態(tài),等待線程調(diào)度器的再次調(diào)度喻频,來達到運行狀態(tài)
(3)線程消亡有如下幾種情況:
- a.
run()
或call()
方法執(zhí)行完畢缩宜,線程正常結(jié)束 - b.線程拋出一個未捕獲的Exception或Error
- c.直接調(diào)用該線程的
stop()
方法來結(jié)束線程(該方法容易導致死鎖,不推薦使用)
(4)一個線程到達消亡狀態(tài)后將無法被恢復為其他狀態(tài)甥温,不能start()重新達到就緒狀態(tài)锻煌,否者會拋出IllegalThreadException()
(5)后臺線程與前臺線程共死。如果前臺前臺線程全部消亡姻蚓,后臺線程也會隨之消宋梧。垃圾消息機制就是典型的后臺線程。后臺線程的子線程也是后臺線程
(6)釋放同步監(jiān)視器的鎖時機:
- a.同步方法史简、同步代碼塊結(jié)束
- b.同步方法乃秀、同步代碼快中出現(xiàn)未處理的Error或Exception
-
c.同步方法、同步代碼快執(zhí)行了同步監(jiān)視器的
wait()
方法圆兵,當前線程暫停
(7)Java1.5出現(xiàn)的同步鎖Lock
- a.ReadWriteLock(讀寫鎖)跺讯,允許對共享資源并發(fā)訪問,實現(xiàn)類有ReentrantReadWriteLock
- b.Lock,實現(xiàn)類為ReentrantLock殉农,此同步鎖較為常用
- c.提供方法有
例:
tryLock() 適用于非塊結(jié)構
lockInterruptibly() 獲取終端鎖
tryLock(long time,TimeUnit unit); 獲取超時失效鎖
<5>.線程相關API
isAlive() 當線程處于就緒刀脏,運行,阻塞三種狀態(tài)時返回true超凳;當線程處于新建或者消亡狀態(tài)時為false愈污。
join() 調(diào)用該方法時所在線程將被阻塞,等待被加入的線程執(zhí)行完畢后才能達到就緒狀態(tài)轮傍。
join(long milles) 阻塞的最長時間是milles
setDaemon(false flag) 設置線程是后臺線程
static sleep(long millis)讓當前正在執(zhí)行的線程睡眠
static yield() 讓當前正在執(zhí)行的線程讓步(暫停)暂雹,會達到就緒狀態(tài)
class ThreadClass extends Thread
{
public void run(){
//線程運行體
for(int x=0 ; x<1000; x++){
System.out.println(Thread.currentThread().getName()+"------"+x);
}
}
public static void main(String[] args)throws Exception{
for(int x=0; x<100; x++){
if(x == 20){
ThreadClass thread = new ThreadClass();
thread.start();
//調(diào)用join方法后主線程會等待ThreadClass線程運行完畢后才運行
thread.join();
}
System.out.println(Thread.currentThread().getName()+"------"+x);
}
}
}
<6>.領域驅(qū)動設計(DDD,Domain Driven Design)一種流行的面向?qū)ο笤O計方式,認為每個類都應該是完整的領域?qū)ο蟠匆梗瑢ψ约撼蓡T進行計算的操作應該自己定義方法進行杭跪,而不是在外部類定義。這樣才能保證該對象的完整性與一致性驰吓。
<7>.通過使用BlockingQueue來做到線程通訊的目的(不使用同步)
BlockingQueue
是一個線程同步工具涧尿,是Queue
的子接口,向隊列中存入元素時如果隊列已滿檬贰,該線程將被阻塞姑廉;向隊列中取出元素時如果隊列已空,則該線程被阻塞
方法解析:
添加的方法
<1>.add(e):隊尾插入元素翁涤,當隊列已滿時拋出異常
<2>.offer(e):隊尾插入元素桥言,當隊列已滿時方法返回值為false萌踱,元素無法存入隊列
<3>.put(e):隊尾插入元素,當隊列已滿時方法會阻塞住線程
刪除的方法
<1>.remove():隊頭刪除元素限书,當隊列為空時拋出異常
<2>.poll():隊頭刪除元素虫蝶,當隊列為空時方法返回值為false,元素獲取為null
<3>.take():隊頭刪除元素倦西,當隊列為空時會阻塞住線程
獲取不刪除的方法
<1>.element():隊頭獲取元素,不刪除赁严。隊列為空時拋出異常
<2>.peek():隊頭獲取元素扰柠,不刪除,隊列為空時方法返回值為false疼约,元素獲取為null
實現(xiàn)類:
<1>. ArrayBlockingQueue 基于數(shù)組實現(xiàn)的BlockingQueue隊列
<2>. LinkedBlockingQueue 基于鏈表實現(xiàn)的BlockingQueue隊列
<3>. PriorityBlockingQueue 按照元素大小排序的隊列卤档,取出來的元素是最小元素,可以使用Comparator進行定制
<4>. SynchronousQueue 同步隊列程剥,對該隊列的存取操作必須交替進行
<5>. DelayQueue 特殊的BlockingQueue劝枣,底層基于 PriorityBlockingQueue 實現(xiàn),要求集合元素實現(xiàn)Delay接口织鲸,其中元素會按getDalay()返回值大小進行排序
代碼示例:
class Producer extends Thread
{
private BlockingQueue<String> bq;
public Producer(BlockingQueue<String> bq){
this.bq = bq;
}
public void run(){
String[] arr = new String[]{"Java","Struts","Spring"};
for(int x=0; x<99999999; x++){
System.out.println(Thread.currentThread().getName()+"生產(chǎn)者準備生產(chǎn)集合元素舔腾!");
try{
//Thread.sleep(220);
bq.put(arr[x % 3]);
}
catch(Exception e){e.printStackTrace();}
System.out.println(Thread.currentThread().getName()+"生產(chǎn)完成"+bq);
}
}
}
class Consumer extends ThreadClass
{
private BlockingQueue<String> bq;
public Consumer(BlockingQueue<String> bq){
this.bq = bq;
}
public void run(){
while(true){
System.out.println(Thread.currentThread().getName()+"消費者準備消費集合元素");
try{
//Thread.sleep(220);
System.out.println(Thread.currentThread().getName()+"消費完成"+bq.take());
}
catch(Exception e){e.printStackTrace();}
}
}
}
class BlockingQueueTest
{
public static void main(String[] args){
BlockingQueue<String> bq = new ArrayBlockingQueue<String>(4);
new Producer(bq).start();
new Producer(bq).start();
new Producer(bq).start();
new Consumer(bq).start();
}
}
8.網(wǎng)絡相關
<1>.URLDecoder 和 URLEncoder 主要用于完成普通字符串和application/x-www-from-urlencoded MIME
字符串之間的相互裝換。
-
a.URLDecoder 可以把亂碼特殊字符串轉(zhuǎn)換為中文字符搂擦,是解碼的過程稳诚。通過
URLDecoder.decode(String str,String enc);
enc為指定字符集 -
b.URLEncoder 可以把中文字符裝換為特殊字符串,是編碼的過程瀑踢。通過
URLEncoder.encode(String str,String enc);
<2>.URL(Uniform Resource Locator) 對象代表統(tǒng)一資源定位器扳还,指向互聯(lián)網(wǎng)資源的指針。URI(Uniform Resource Identifiers)橱夭,這是Java提供的一個類氨距,代表一個統(tǒng)一資源標識符,不能用于定位資源棘劣,它的唯一作用就是解析俏让,可以將URL理解成URI的特例,類與對象的那種關系呈础。
<3>.HttpUrlConnection
或者 UrlConnection
一般都要設置很多請求頭舆驶,具體請參考我的Http筆記。對于get請求一定要建立連接通過 conn.connect();
對于Post請求一定要設置 conn.setDoOutput(true)
和 conn.setDoInput(true)
<4>.IP協(xié)議全稱 Internet Protocal,通過該協(xié)議使Internet成為一個允許連接不同類型的計算機和不用操作系統(tǒng)的網(wǎng)絡而钞,其負責將消息從一個主機傳送到另一個主機沙廉,消息傳送過程中給分割成一個個的小包。不過IP協(xié)議不能解決數(shù)據(jù)在傳輸過程中可能出現(xiàn)的全部問題臼节。所以需要 TCP協(xié)議 提供通信服務撬陵。TCP協(xié)議,提供可靠并且無差錯的通信服務珊皿。讓它們建立一個鏈接,是一條虛擬鏈路巨税。TCP協(xié)議 有自己的重發(fā)機制蟋定,提供了可靠的通信連接,適應網(wǎng)上的各種變化草添。** 綜上所述**驶兜,這兩個協(xié)議功能上不盡相同,也可以分開來單獨使用远寸,不過她們是在同一時期作為一個協(xié)議來設計的抄淑,并且功能上也是互補的。所以兩者只有結(jié)合起來驰后,才能保證Internet在復雜的環(huán)境下運行肆资。
<5>.TCP在使用時Socket對象可以設置超時時間,通過setSoTimeOut(s)
或者構造方法的參數(shù)灶芝。如果超出了該時間限制郑原,那么這些方法就會拋出SocketTimeOutException異常∫固椋可以捕獲做相應的處理.
<6>.使用ServerSocket如何群發(fā)信息犯犁。因為Socket與ServerSocket建立連接后,都會在服務端新建一個Socket钠乏,那么我們通過記錄服務端有多少個新建的Socket既可以向多用戶發(fā)送信息
<7>.可以使用NIO栖秕、AIO、代理服務器Proxy等為Socket服務晓避,前者可做阻塞式Socket簇捍,這個以后需要時可以來看一下
9.反射相關
<1>.類加載器負責將.class文件加載到內(nèi)存中,并生成 java.lang.Class
對象俏拱。JVM 啟動時暑塑,會形成由三個類加載器組成的初始類加載器層次結(jié)構
- a.Bootstrap ClassLoader:根類加載器,負責加載Java的核心類锅必,不是 java.lang.ClassLoader 的子類事格,有JVM自身實現(xiàn)。諸如——rt.jar等文件
- b.Extension ClassLoader:擴展類加載器搞隐,負責加載JRE的擴展目錄中的Jar包
- c.System ClassLoader:系統(tǒng)類加載器驹愚,負責在JVM啟動時加載來自java命令的-classpath或者java.class.path系統(tǒng)屬性
<2>.URLClassLoader 類是系統(tǒng)加載器和擴展類加載器的父類,能夠從本地文件系統(tǒng)或者遠程主機獲取二進制文件來加載類劣纲。
<3>.Java8新特性:新增的方法參數(shù)反射
以上是全部筆記逢捺,我懷疑自己只有很久以后才會再回來看Java了,這是第幾次看基礎知識了....