博客沒有寫作。
國家大事件幾多。
Vincent Jia 博客to be a better man, to be a bad man. |
2011年12月8日 #
The collections framework is a unified architecture for representing and manipulating collections, allowing them to be manipulated independently of the details of their representation. It reduces programming effort while increasing performance. It allows for interoperability among unrelated APIs, reduces effort in designing and learning new APIs, and fosters software reuse. The framework is based on fourteen collection interfaces. It includes implementations of these interfaces, and algorithms to manipulate them.Overview
“開-閉”原則 (Open-Closed principle, OCP)
一個軟件實體應(yīng)當對擴展開放,對修改關(guān)閉。
Software entities should be open for extension, but closed for modification.
在設(shè)計一個模塊的時候,應(yīng)當使這個模塊可以在不被修改的前提下被擴展。
“可變性的封裝原則”從工程的角度講解了如何實現(xiàn)“開-閉”原則。
“可變性的封裝原則”意味著兩點:
1.一種可變性不應(yīng)當散落在代碼的很多角落里,而應(yīng)當被封裝到一個對象里面。繼承應(yīng)當被看做是封裝變化的方法,而不應(yīng)當被認為是從一般的對象生成特殊的對象方法。
2.一種可變性不應(yīng)當與另一種可變性混合在一起。所有的類圖的繼承結(jié)構(gòu)一般不會超過兩層,不然就意味著將兩種不同的可變性混合在一起。
“開-閉”原則與其他原則的關(guān)系:
里氏代換原則是,任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。
里氏代換原則是對“開-閉”原則的補充。實現(xiàn)“開-閉”原則的關(guān)鍵步驟就是抽象化,而基類與子類的繼承關(guān)系就是抽象化的具體體現(xiàn),所以里氏代換原則是對實現(xiàn)抽象化的具體步驟的規(guī)范。違反里氏代換原則的,也違背“開-閉”原則,反之不一定成立。
依賴倒轉(zhuǎn)原則是,要依賴于抽象,不要依賴于實現(xiàn)。
“開-閉”原則是目標,依賴倒轉(zhuǎn)原則是手段。
合成/聚合復(fù)用原則是,要盡量使用合成/聚合,而不是繼承關(guān)系達到復(fù)用的目的。
合成/聚合復(fù)用原則與里氏代換原則相輔相成,兩者都是實現(xiàn)“開-閉”原則的具體步驟的規(guī)范。
迪米特法則是,一個軟件實體應(yīng)當與盡可能少的其他實體發(fā)生相互作用。
一個遵守迪米特原則設(shè)計出來的系統(tǒng)在功能需要擴展時,會相對更容易地做到對修改的關(guān)閉。
接口隔離原則是,應(yīng)當為客戶端提供盡可能小的單獨的接口,而不是提供大的總接口。
接口隔離原則與廣義的迪米特法則都是對一個軟件實體與其他的軟件實體的通信的限制。遵循接口隔離原則,會使一個軟件系統(tǒng)在功能擴展的過程當中,不會將修改的壓力傳遞到其他的對象。
一個重構(gòu)方法的討論
“將條件轉(zhuǎn)移語句改寫成為多態(tài)性”是一條廣為流傳的代碼重構(gòu)做法。
這一做法本身并不能保證“開-閉”原則,應(yīng)當以“開-閉”原則判斷是否需要改寫成多態(tài)。條件轉(zhuǎn)移并不是錯誤,如果需要,完全可以選擇使用條件轉(zhuǎn)移。
如果一個條件轉(zhuǎn)移語句確實封裝了某種商務(wù)邏輯的可變性,那么將此種可變性封裝起來就符合“開-閉”原則設(shè)計思想了。如果一個條件轉(zhuǎn)移語句沒有涉及重要的商務(wù)邏輯,或者不會隨著時間的變化而變化,也不意味著任何的可擴展性,那么它就沒有涉及任何有意義的可變性。這時候?qū)⑦@個條件轉(zhuǎn)移語句改寫成多態(tài)性就是一種沒有意義的浪費。
抽象類應(yīng)當擁有盡可能多的共同代碼
在一個繼承的等級結(jié)構(gòu)中,共同的代碼應(yīng)當盡量向等級結(jié)構(gòu)的上方移動。把重復(fù)的代碼從子類里面移動到超類里面,可以提高代碼的復(fù)用率。在代碼發(fā)生改變時,設(shè)計師之需要修改一個地方。
抽象類應(yīng)當擁有盡可能少的數(shù)據(jù)
與代碼的移動方向相反,數(shù)據(jù)的移動方向是從抽象類到具體類,向等級結(jié)構(gòu)的下方移動。一個對象的數(shù)據(jù)不論是否使用都會占用資源,所以應(yīng)當放到等級結(jié)構(gòu)的低端。
什么時候才應(yīng)當使用繼承復(fù)用
1.子類是超類的一個特殊種類,而不是超類的一個角色,Is-A才符合繼承關(guān)系。
2.永遠不會出現(xiàn)需要將子類換成另一個類的子類的情況。
3.子類具有擴展超類的責(zé)任,而不是具有置換掉(Override)和注銷掉(Nullify)超類的責(zé)任。
4.只有在分類學(xué)角度上有意義時,才可以使用繼承,不要從工具類繼承。
前段時間系統(tǒng)升級時遭遇了OOM,具體解決過程見 遭遇OutOfMemoryError;
為了鞏固對于java啟動各項參數(shù)的認識,決定將所有參數(shù)列舉出來,并一一解釋,以便后查;
java啟動參數(shù)共分為三類;
其一是標準參數(shù)(-),所有的JVM實現(xiàn)都必須實現(xiàn)這些參數(shù)的功能,而且向后兼容;
其二是非標準參數(shù)(-X),默認jvm實現(xiàn)這些參數(shù)的功能,但是并不保證所有jvm實現(xiàn)都滿足,且不保證向后兼容;
其三是非Stable參數(shù)(-XX),此類參數(shù)各個jvm實現(xiàn)會有所不同,將來可能會隨時取消,需要慎重使用;
本文主要描述標準參數(shù)部分,剩下的兩個部分將會陸續(xù)推出;
標準參數(shù)列表如下:
-client
設(shè)置jvm使用client模式,特點是啟動速度比較快,但運行時性能和內(nèi)存管理效率不高,通常用于客戶端應(yīng)用程序或者PC應(yīng)用開發(fā)和調(diào)試。
-server
設(shè)置jvm使server模式,特點是啟動速度比較慢,但運行時性能和內(nèi)存管理效率很高,適用于生產(chǎn)環(huán)境。在具有64位能力的jdk環(huán)境下將默認啟用該模式,而忽略-client參數(shù)。
-agentlib:libname[=options]
用于裝載本地lib包;
其中l(wèi)ibname為本地代理庫文件名,默認搜索路徑為環(huán)境變量PATH中的路徑,options為傳給本地庫啟動時的參數(shù),多個參數(shù)之間用逗號分隔。在Windows平臺上jvm搜索本地庫名為libname.dll的文件,在linux上jvm搜索本地庫名為libname.so的文件,搜索路徑環(huán)境變量在不同系統(tǒng)上有所不同,比如Solaries上就默認搜索LD_LIBRARY_PATH。
比如:-agentlib:hprof
用來獲取jvm的運行情況,包括CPU、內(nèi)存、線程等的運行數(shù)據(jù),并可輸出到指定文件中;windows中搜索路徑為JRE_HOME/bin/hprof.dll。
-agentpath:pathname[=options]
按全路徑裝載本地庫,不再搜索PATH中的路徑;其他功能和agentlib相同;更多的信息待續(xù),在后續(xù)的JVMTI部分會詳述。
-classpath classpath
-cp classpath
告知jvm搜索目錄名、jar文檔名、zip文檔名,之間用分號;分隔;使用-classpath后jvm將不再使用CLASSPATH中的類搜索路徑,如果-classpath和CLASSPATH都沒有設(shè)置,則jvm使用當前路徑(.)作為類搜索路徑。
jvm搜索類的方式和順序為:Bootstrap,Extension,User。
Bootstrap中的路徑是jvm自帶的jar或zip文件,jvm首先搜索這些包文件,用System.getProperty("sun.boot.class.path")可得到搜索路徑。
Extension是位于JRE_HOME/lib/ext目錄下的jar文件,jvm在搜索完Bootstrap后就搜索該目錄下的jar文件,用System.getProperty("java.ext.dirs")可得到搜索路徑。
User搜索順序為當前路徑.、CLASSPATH、-classpath,jvm最后搜索這些目錄,用System.getProperty("java.class.path")可得到搜索路徑。
-Dproperty=value
設(shè)置系統(tǒng)屬性名/值對,運行在此jvm之上的應(yīng)用程序可用System.getProperty("property")得到value的值。
如果value中有空格,則需要用雙引號將該值括起來,如-Dname="space string"。
該參數(shù)通常用于設(shè)置系統(tǒng)級全局變量值,如配置文件路徑,以便該屬性在程序中任何地方都可訪問。
-enableassertions[:<package name>"..." | :<class name> ]
-ea[:<package name>"..." | :<class name> ]
上述參數(shù)就用來設(shè)置jvm是否啟動斷言機制(從JDK 1.4開始支持),缺省時jvm關(guān)閉斷言機制。
用-ea 可打開斷言機制,不加<packagename>和classname時運行所有包和類中的斷言,如果希望只運行某些包或類中的斷言,可將包名或類名加到-ea之后。例如要啟動包com.wombat.fruitbat中的斷言,可用命令java -ea:com.wombat.fruitbat...<Main Class>。
-disableassertions[:<package name>"..." | :<class ; ]
-da[:<package name>"..." | :<class name> ]
用來設(shè)置jvm關(guān)閉斷言處理,packagename和classname的使用方法和-ea相同,jvm默認就是關(guān)閉狀態(tài)。
該參數(shù)一般用于相同package內(nèi)某些class不需要斷言的場景,比如com.wombat.fruitbat需要斷言,但是com.wombat.fruitbat.Brickbat該類不需要,則可以如下運行:
java -ea:com.wombat.fruitbat...-da:com.wombat.fruitbat.Brickbat <Main Class>。
-enablesystemassertions
-esa
激活系統(tǒng)類的斷言。
-disablesystemassertions
-dsa
關(guān)閉系統(tǒng)類的斷言。
-jar
指定以jar包的形式執(zhí)行一個應(yīng)用程序。
要這樣執(zhí)行一個應(yīng)用程序,必須讓jar包的manifest文件中聲明初始加載的Main-class,當然那Main-class必須有public static void main(String[] args)方法。
-javaagent:jarpath[=options]
指定jvm啟動時裝入java語言設(shè)備代理。
Jarpath文件中的mainfest文件必須有Agent-Class屬性。代理類也必須實現(xiàn)公共的靜態(tài)public static void premain(String agentArgs, Instrumentation inst)方法(和main方法類似)。當jvm初始化時,將按代理類的說明順序調(diào)用premain方法;具體參見java.lang.instrument軟件包的描述。
-verbose
-verbose:class
輸出jvm載入類的相關(guān)信息,當jvm報告說找不到類或者類沖突時可此進行診斷。
-verbose:gc
輸出每次GC的相關(guān)情況。
-verbose:jni
輸出native方法調(diào)用的相關(guān)情況,一般用于診斷jni調(diào)用錯誤信息。
-version
輸出java的版本信息,比如jdk版本、vendor、model。
-version:release
指定class或者jar運行時需要的jdk版本信息;若指定版本未找到,則以能找到的系統(tǒng)默認jdk版本執(zhí)行;一般情況下,對于jar文件,可以在manifest文件中指定需要的版本信息,而不是在命令行。
release中可以指定單個版本,也可以指定一個列表,中間用空格隔開,且支持復(fù)雜組合,比如:
-version:"1.5.0_04 1.5*&1.5.1_02+"
指定class或者jar需要jdk版本為1.5.0_04或者是1.5系列中比1.5.1_02更高的所有版本。
-showversion
輸出java版本信息(與-version相同)之后,繼續(xù)輸出java的標準參數(shù)列表及其描述。
-?
-help
輸出java標準參數(shù)列表及其描述。
-X
輸出非標準的參數(shù)列表及其描述。
以上的這些參數(shù)我們經(jīng)常會在很多情況下用到多個的組合,比如我們在用JProfiler進行跟蹤監(jiān)控時,需要在被監(jiān)控java啟動參數(shù)中加上如下配置:
-agentlib:jprofilerti=port=8849 -Xbootclasspath/a:/usr/local/jprofiler5/bin/agent.jar
其中就用到兩個-agentlib和-X參數(shù),bootclasspath參數(shù)的詳細信息將會在非標準參數(shù)中詳細說明。
轉(zhuǎn)自:http://blog.csdn.net/sfdev/article/details/2062042
這篇文章補充說明了-X、-XX參數(shù)的說明:Java命令行運行參數(shù)說明大全(偷來的)
1 web容器啟動,初始化ActionServlet,加載struts-config.xml,根據(jù)請求路徑和信息找到ActionBean與FormBean
2 確定將要調(diào)用的ActionBean與FormBean,將請求中包含的值填充到FormBean中(Action中要準備好ActionMapping的參數(shù))
3 struts將請求分發(fā)到相應(yīng)的的ActionBean處理,ActionMapping參數(shù)ActionForm參數(shù)request,resposne都做為參數(shù)傳給處理請求的ActionBean的execute方法
4 Action調(diào)用業(yè)務(wù)邏輯方法,得到返回值A(chǔ)ctionForward對象
5 控制控重回ActionServlet,根據(jù)Action返回的ActionForward對象,轉(zhuǎn)發(fā)到相應(yīng)的頁面
6 處理結(jié)果返回瀏覽器