java代碼量消減,減少代碼量

Java代碼優(yōu)化有哪些常用的方法

1、 盡量指定類的final修飾符 帶有final修飾符的類是不可派生的。

目前成都創(chuàng)新互聯(lián)公司已為成百上千的企業(yè)提供了網(wǎng)站建設、域名、網(wǎng)頁空間、網(wǎng)站托管維護、企業(yè)網(wǎng)站設計、橫山網(wǎng)站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

在Java核心API中,有許多應用final的例子,例如java.lang.String。為String類指定final防止了人們覆蓋length()方法。另外,如果指定一個類為final,則該類所有的方法都是final。Java編譯器會尋找機會內聯(lián)(inline)所有的final方法(這和具體的編譯器實現(xiàn)有關)。此舉能夠使性能平均提高50% 。

2、 盡量重用對象。

特別是String 對象的使用中,出現(xiàn)字符串連接情況時應用StringBuffer 代替。由于系統(tǒng)不僅要花時間生成對象,以后可能還需花時間對這些對象進行垃圾回收和處理。因此,生成過多的對象將會給程序的性能帶來很大的影響。

3、 盡量使用局部變量,調用方法時傳遞的參數(shù)以及在調用中創(chuàng)建的臨時變量都保存在棧(Stack)中,速度較快。

其他變量,如靜態(tài)變量、實例變量等,都在堆(Heap)中創(chuàng)建,速度較慢。另外,依賴于具體的編譯器/JVM,局部變量還可能得到進一步優(yōu)化。請參見《盡可能使用堆棧變量》。

4、 不要重復初始化變量

默認情況下,調用類的構造函數(shù)時, Java會把變量初始化成確定的值:所有的對象被設置成null,整數(shù)變量(byte、short、int、long)設置成0,float和double變量設置成0.0,邏輯值設置成false。當一個類從另一個類派生時,這一點尤其應該注意,因為用new關鍵詞創(chuàng)建一個對象時,構造函數(shù)鏈中的所有構造函數(shù)都會被自動調用。

5、 在JAVA + ORACLE 的應用系統(tǒng)開發(fā)中,java中內嵌的SQL語句盡量使用大寫的形式,以減輕ORACLE解析器的解析負擔。

6、 Java 編程過程中,進行數(shù)據(jù)庫連接、I/O流操作時務必小心,在使用完畢后,即使關閉以釋放資源。

因為對這些大對象的操作會造成系統(tǒng)大的開銷,稍有不慎,會導致嚴重的后果。

7、 由于JVM的有其自身的GC機制,不需要程序開發(fā)者的過多考慮,從一定程度上減輕了開發(fā)者負擔,但同時也遺漏了隱患,過分的創(chuàng)建對象會消耗系統(tǒng)的大量內存,嚴重時會導致內存泄露,因此,保證過期對象的及時回收具有重要意義。

JVM回收垃圾的條件是:對象不在被引用;然而,JVM的GC并非十分的機智,即使對象滿足了垃圾回收的條件也不一定會被立即回收。所以,建議我們在對象使用完畢,應手動置成null。

8、 在使用同步機制時,應盡量使用方法同步代替代碼塊同步。

9、 盡量減少對變量的重復計算

例如:for(int i = 0;i list.size; i ++) {

}

應替換為:

for(int i = 0,int len = list.size();i len; i ++){

}

10、盡量采用lazy loading 的策略,即在需要的時候才開始創(chuàng)建。

例如: String str = “aaa”;

if(i == 1) {

list.add(str);

}

應替換為:

if(i == 1) {

String str = “aaa”;

list.add(str);

}

11、慎用異常

異常對性能不利。拋出異常首先要創(chuàng)建一個新的對象。Throwable接口的構造函數(shù)調用名為fillInStackTrace()的本地(Native)方法,fillInStackTrace()方法檢查堆棧,收集調用跟蹤信息。只要有異常被拋出,VM就必須調整調用堆棧,因為在處理過程中創(chuàng)建了一個新的對象。 異常只能用于錯誤處理,不應該用來控制程序流程。

12、不要在循環(huán)中使用:

Try {

} catch() {

}

應把其放置在最外層。

13、StringBuffer 的使用:

StringBuffer表示了可變的、可寫的字符串。

有三個構造方法 :

StringBuffer (); //默認分配16個字符的空間

StringBuffer (int size); //分配size個字符的空間

StringBuffer (String str); //分配16個字符+str.length()個字符空間

你可以通過StringBuffer的構造函數(shù)來設定它的初始化容量,這樣可以明顯地提升性能。

這里提到的構造函數(shù)是StringBuffer(int length),length參數(shù)表示當前的StringBuffer能保持的字符數(shù)量。你也可以使用ensureCapacity(int minimumcapacity)方法在StringBuffer對象創(chuàng)建之后設置它的容量。首先我們看看StringBuffer的缺省行為,然后再找出一條更好的提升性能的途徑。

StringBuffer在內部維護一個字符數(shù)組,當你使用缺省的構造函數(shù)來創(chuàng)建StringBuffer對象的時候,因為沒有設置初始化字符長度,StringBuffer的容量被初始化為16個字符,也就是說缺省容量就是16個字符。當StringBuffer達到最大容量的時候,它會將自身容量增加到當前的2倍再加2,也就是(2*舊值+2)。如果你使用缺省值,初始化之后接著往里面追加字符,在你追加到第16個字符的時候它會將容量增加到34(2*16+2),當追加到34個字符的時候就會將容量增加到70(2*34+2)。無論何事只要StringBuffer到達它的最大容量它就不得不創(chuàng)建一個新的字符數(shù)組然后重新將舊字符和新字符都拷貝一遍――這也太昂貴了點。所以總是給StringBuffer設置一個合理的初始化容量值是錯不了的,這樣會帶來立竿見影的性能增益。StringBuffer初始化過程的調整的作用由此可見一斑。所以,使用一個合適的容量值來初始化StringBuffer永遠都是一個最佳的建議。

14、合理的使用Java類 java.util.Vector。

簡單地說,一個Vector就是一個java.lang.Object實例的數(shù)組。Vector與數(shù)組相似,它的元素可以通過整數(shù)形式的索引訪問。但是,Vector類型的對象在創(chuàng)建之后,對象的大小能夠根據(jù)元素的增加或者刪除而擴展、縮小。請考慮下面這個向Vector加入元素的例子:

Object bj = new Object();

Vector v = new Vector(100000);

for(int I=0;

I100000; I++) { v.add(0,obj); }

除非有絕對充足的理由要求每次都把新元素插入到Vector的前面,否則上面的代碼對性能不利。在默認構造函數(shù)中,Vector的初始存儲能力是10個元素,如果新元素加入時存儲能力不足,則以后存儲能力每次加倍。Vector類就對象StringBuffer類一樣,每次擴展存儲能力時,所有現(xiàn)有的元素都要復制到新的存儲空間之中。下面的代碼片段要比前面的例子快幾個數(shù)量級:

Object bj = new Object();

Vector v = new Vector(100000);

for(int I=0; I100000; I++) { v.add(obj); }

同樣的規(guī)則也適用于Vector類的remove()方法。由于Vector中各個元素之間不能含有“空隙”,刪除除最后一個元素之外的任意其他元素都導致被刪除元素之后的元素向前移動。也就是說,從Vector刪除最后一個元素要比刪除第一個元素“開銷”低好幾倍。

假設要從前面的Vector刪除所有元素,我們可以使用這種代碼:

for(int I=0; I100000; I++)

{

v.remove(0);

}

但是,與下面的代碼相比,前面的代碼要慢幾個數(shù)量級:

for(int I=0; I100000; I++)

{

v.remove(v.size()-1);

}

從Vector類型的對象v刪除所有元素的最好方法是:

v.removeAllElements();

假設Vector類型的對象v包含字符串“Hello”??紤]下面的代碼,它要從這個Vector中刪除“Hello”字符串:

String s = "Hello";

int i = v.indexOf(s);

if(I != -1) v.remove(s);

這些代碼看起來沒什么錯誤,但它同樣對性能不利。在這段代碼中,indexOf()方法對v進行順序搜索尋找字符串“Hello”,remove(s)方法也要進行同樣的順序搜索。改進之后的版本是:

String s = "Hello";

int i = v.indexOf(s);

if(I != -1) v.remove(i);

這個版本中我們直接在remove()方法中給出待刪除元素的精確索引位置,從而避免了第二次搜索。一個更好的版本是:

String s = "Hello"; v.remove(s);

最后,我們再來看一個有關Vector類的代碼片段:

for(int I=0; I++;I v.length)

如果v包含100,000個元素,這個代碼片段將調用v.size()方法100,000次。雖然size方法是一個簡單的方法,但它仍舊需要一次方法調用的開銷,至少JVM需要為它配置以及清除堆棧環(huán)境。在這里,for循環(huán)內部的代碼不會以任何方式修改Vector類型對象v的大小,因此上面的代碼最好改寫成下面這種形式:

int size = v.size(); for(int I=0; I++;Isize)

雖然這是一個簡單的改動,但它仍舊贏得了性能。畢竟,每一個CPU周期都是寶貴的。

15、當復制大量數(shù)據(jù)時,使用System.arraycopy()命令。

int[] src={1,3,5,6,7,8};

int[] dest = new int[6];

System.arraycopy(src, 0, dest, 0, 6);

src:源數(shù)組; srcPos:源數(shù)組要復制的起始位置;

dest:目的數(shù)組; destPos:目的數(shù)組放置的起始位置;

length:復制的長度.

注意:src and dest都必須是同類型或者可以進行轉換類型的數(shù)組.

16、代碼重構:增強代碼的可讀性。

public class ShopCart {

private List carts ;

public void add (Object item) {

if(carts == null) {

carts = new ArrayList();

}

crts.add(item);

}

public void remove(Object item) {

if(carts. contains(item)) {

carts.remove(item);

}

}

public List getCarts() {

//返回只讀列表

return Collections.unmodifiableList(carts);

}

//不推薦這種方式

//this.getCarts().add(item);

}

17、不用new關鍵詞創(chuàng)建類的實例

用new關鍵詞創(chuàng)建類的實例時,構造函數(shù)鏈中的所有構造函數(shù)都會被自動調用。但如果一個對象實現(xiàn)了Cloneable接口,我們可以調用它的clone()方法。clone()方法不會調用任何類構造函數(shù)。

在使用設計模式(Design Pattern)的場合,如果用Factory模式創(chuàng)建對象,則改用clone()方法創(chuàng)建新的對象實例非常簡單。例如,下面是Factory模式的一個典型實現(xiàn):

public static Credit getNewCredit() {

return new Credit();

}

改進后的代碼使用clone()方法,如下所示:

private static Credit BaseCredit = new Credit();

public static Credit getNewCredit() {

return (Credit) BaseCredit.clone();

}

上面的思路對于數(shù)組處理同樣很有用。

18、乘法和除法

考慮下面的代碼:

for (val = 0; val 100000; val +=5) {

alterX = val * 8; myResult = val * 2;

}

用移位操作替代乘法操作可以極大地提高性能。下面是修改后的代碼:

for (val = 0; val 100000; val += 5) {

alterX = val 3; myResult = val 1;

}

修改后的代碼不再做乘以8的操作,而是改用等價的左移3位操作,每左移1位相當于乘以2。相應地,右移1位操作相當于除以2。值得一提的是,雖然移位操作速度快,但可能使代碼比較難于理解,所以最好加上一些注釋。

19、在JSP頁面中關閉無用的會話。

一個常見的誤解是以為session在有客戶端訪問時就被創(chuàng)建,然而事實是直到某server端程序調用HttpServletRequest.getSession(true)這樣的語句時才被創(chuàng)建,注意如果JSP沒有顯示的使用 關閉session,則JSP文件在編譯成Servlet時將會自動加上這樣一條語句HttpSession session = HttpServletRequest.getSession(true);這也是JSP中隱含的session對象的來歷。由于session會消耗內存資源,因此,如果不打算使用session,應該在所有的JSP中關閉它。

對于那些無需跟蹤會話狀態(tài)的頁面,關閉自動創(chuàng)建的會話可以節(jié)省一些資源。使用如下page指令:%@ page session="false"%

20、JDBC與I/O

如果應用程序需要訪問一個規(guī)模很大的數(shù)據(jù)集,則應當考慮使用塊提取方式。默認情況下,JDBC每次提取32行數(shù)據(jù)。舉例來說,假設我們要遍歷一個5000行的記錄集,JDBC必須調用數(shù)據(jù)庫157次才能提取到全部數(shù)據(jù)。如果把塊大小改成512,則調用數(shù)據(jù)庫的次數(shù)將減少到10次。

21、Servlet與內存使用

許多開發(fā)者隨意地把大量信息保存到用戶會話之中。一些時候,保存在會話中的對象沒有及時地被垃圾回收機制回收。從性能上看,典型的癥狀是用戶感到系統(tǒng)周期性地變慢,卻又不能把原因歸于任何一個具體的組件。如果監(jiān)視JVM的堆空間,它的表現(xiàn)是內存占用不正常地大起大落。

解決這類內存問題主要有二種辦法。第一種辦法是,在所有作用范圍為會話的Bean中實現(xiàn)HttpSessionBindingListener接口。這樣,只要實現(xiàn)valueUnbound()方法,就可以顯式地釋放Bean使用的資源。

另外一種辦法就是盡快地把會話作廢。大多數(shù)應用服務器都有設置會話作廢間隔時間的選項。另外,也可以用編程的方式調用會話的setMaxInactiveInterval()方法,該方法用來設定在作廢會話之前,Servlet容器允許的客戶請求的最大間隔時間,以秒計。

22、使用緩沖標記

一些應用服務器加入了面向JSP的緩沖標記功能。例如,BEA的WebLogic Server從6.0版本開始支持這個功能,Open Symphony工程也同樣支持這個功能。JSP緩沖標記既能夠緩沖頁面片斷,也能夠緩沖整個頁面。當JSP頁面執(zhí)行時,如果目標片斷已經(jīng)在緩沖之中,則生成該片斷的代碼就不用再執(zhí)行。頁面級緩沖捕獲對指定URL的請求,并緩沖整個結果頁面。對于購物籃、目錄以及門戶網(wǎng)站的主頁來說,這個功能極其有用。對于這類應用,頁面級緩沖能夠保存頁面執(zhí)行的結果,供后繼請求使用。

23、選擇合適的引用機制

在典型的JSP應用系統(tǒng)中,頁頭、頁腳部分往往被抽取出來,然后根據(jù)需要引入頁頭、頁腳。當前,在JSP頁面中引入外部資源的方法主要有兩種:include指令,以及include動作。

include指令:例如%@ include file="copyright.html" %。該指令在編譯時引入指定的資源。在編譯之前,帶有include指令的頁面和指定的資源被合并成一個文件。被引用的外部資源在編譯時就確定,比運行時才確定資源更高效。

include動作:例如jsp:include page="copyright.jsp" /。該動作引入指定頁面執(zhí)行后生成的結果。由于它在運行時完成,因此對輸出結果的控制更加靈活。但時,只有當被引用的內容頻繁地改變時,或者在對主頁面的請求沒有出現(xiàn)之前,被引用的頁面無法確定時,使用include動作才合算。

24、及時清除不再需要的會話

為了清除不再活動的會話,許多應用服務器都有默認的會話超時時間,一般為30分鐘。當應用服務器需要保存更多會話時,如果內存容量不足,操作系統(tǒng)會把部分內存數(shù)據(jù)轉移到磁盤,應用服務器也可能根據(jù)“最近最頻繁使用”(Most Recently Used)算法把部分不活躍的會話轉儲到磁盤,甚至可能拋出“內存不足”異常。在大規(guī)模系統(tǒng)中,串行化會話的代價是很昂貴的。當會話不再需要時,應當及時調用HttpSession.invalidate()方法清除會話。HttpSession.invalidate()方法通??梢栽趹玫耐顺鲰撁嬲{用。

25、不要將數(shù)組聲明為:public static final 。

26、HashMap的遍歷效率討論

經(jīng)常遇到對HashMap中的key和value值對的遍歷操作,有如下兩種方法:

MapString, String[] paraMap = new HashMapString, String[]();

//第一個循環(huán)

SetString appFieldDefIds = paraMap.keySet();

for (String appFieldDefId : appFieldDefIds) {

String[] values = paraMap.get(appFieldDefId);

......

}

//第二個循環(huán)

for(EntryString, String[] entry : paraMap.entrySet()){

String appFieldDefId = entry.getKey();

String[] values = entry.getValue();

.......

}

第一種實現(xiàn)明顯的效率不如第二種實現(xiàn)。

分析如下 SetString appFieldDefIds = paraMap.keySet(); 是先從HashMap中取得keySet

代碼如下:

public SetK keySet() {

SetK ks = keySet;

return (ks != null ? ks : (keySet = new KeySet()));

}

private class KeySet extends AbstractSetK {

public IteratorK iterator() {

return newKeyIterator();

}

public int size() {

return size;

}

public boolean contains(Object o) {

return containsKey(o);

}

public boolean remove(Object o) {

return HashMap.this.removeEntryForKey(o) != null;

}

public void clear() {

HashMap.this.clear();

}

}

其實就是返回一個私有類KeySet, 它是從AbstractSet繼承而來,實現(xiàn)了Set接口。

再來看看for/in循環(huán)的語法

for(declaration : expression)

statement

在執(zhí)行階段被翻譯成如下各式

for(IteratorE #i = (expression).iterator(); #i.hashNext();){

declaration = #i.next();

statement

}

因此在第一個for語句for (String appFieldDefId : appFieldDefIds) 中調用了HashMap.keySet().iterator()

而這個方法調用了newKeyIterator()

IteratorK newKeyIterator() {

return new KeyIterator();

}

private class KeyIterator extends HashIteratorK {

public K next() {

return nextEntry().getKey();

}

}

所以在for中還是調用了

在第二個循環(huán)for(EntryString, String[] entry : paraMap.entrySet())中使用的Iterator是如下的一個內部

private class EntryIterator extends HashIteratorMap.EntryK,V {

public Map.EntryK,V next() {

return nextEntry();

}

}

此時第一個循環(huán)得到key,第二個循環(huán)得到HashMap的Entry效率就是從循環(huán)里面體現(xiàn)出來的第二個循環(huán)此致可以直接取key和value值而第一個循環(huán)還是得再利用HashMap的get(Object key)來取value值現(xiàn)在看看HashMap的get(Object key)方法

public V get(Object key) {

Object k = maskNull(key);

int hash = hash(k);

int i = indexFor(hash, table.length); //Entry[] table

EntryK,V e = table;

while (true) {

if (e == null)

return null;

if (e.hash == hash eq(k, e.key))

return e.value;

e = e.next;

}

}

其實就是再次利用Hash值取出相應的Entry做比較得到結果,所以使用第一中循環(huán)相當于兩次進入HashMap的Entry

中而第二個循環(huán)取得Entry的值之后直接取key和value,效率比第一個循環(huán)高。其實按照Map的概念來看也應該是用第二個循環(huán)好一點,它本來就是key和value的值對,將key和value分開操作在這里不是個好選擇。

27、array(數(shù)組) 和 ArryList的使用

array([]):最高效;但是其容量固定且無法動態(tài)改變;

ArrayList:容量可動態(tài)增長;但犧牲效率;

基于效率和類型檢驗,應盡可能使用array,無法確定數(shù)組大小時才使用ArrayList!

ArrayList是Array的復雜版本

ArrayList內部封裝了一個Object類型的數(shù)組,從一般的意義來說,它和數(shù)組沒有本質的差別,甚至于ArrayList的許多方法,如Index、IndexOf、Contains、Sort等都是在內部數(shù)組的基礎上直接調用Array的對應方法。

ArrayList存入對象時,拋棄類型信息,所有對象屏蔽為Object,編譯時不檢查類型,但是運行時會報錯。

注:jdk5中加入了對泛型的支持,已經(jīng)可以在使用ArrayList時進行類型檢查。

從這一點上看來,ArrayList與數(shù)組的區(qū)別主要就是由于動態(tài)增容的效率問題了

28、盡量使用HashMap 和ArrayList ,除非必要,否則不推薦使用HashTable和Vector ,后者由于使用同步機制,而導致了性能的開銷。

29、StringBuffer 和StringBuilder的區(qū)別:

java.lang.StringBuffer線程安全的可變字符序列。一個類似于 String 的字符串緩沖區(qū),但不能修改。

StringBuilder。與該類相比,通常應該優(yōu)先使用 java.lang.StringBuilder類,因為它支持所有相同的操作,但由于它不執(zhí)行同步,所以速度更快。為了獲得更好的性能,在構造 StirngBuffer 或 StirngBuilder 時應盡可能指定它的容量。當然,如果你操作的字符串長度不超過 16 個字符就不用了。 相同情況下使用 StirngBuilder 相比使用 StringBuffer 僅能獲得 10%-15% 左右的性能提升,但卻要冒多線程不安全的風險。而在現(xiàn)實的模塊化編程中,負責某一模塊的程序員不一定能清晰地判斷該模塊是否會放入多線程的環(huán)境中運行,因此:除非你能確定你的系統(tǒng)的瓶頸是在 StringBuffer 上,并且確定你的模塊不會運行在多線程模式下,否則還是用 StringBuffer 吧。

30、盡量避免使用split

除非是必須的,否則應該避免使用split,split由于支持正則表達式,所以效率比較低,如果是頻繁的幾十,幾百萬的調用將會耗費大量資源,如果確實需要頻繁的調用split,可以考慮使用apache的 StringUtils.split(string,char),頻繁split的可以緩存結果。

其他補充:

1、及時清除不再使用的對象,設為null

2、盡可能使用final,static等關鍵字

3、盡可能使用buffered對象

如何優(yōu)化代碼使JAVA源文件及編譯后CLASS文件更小

1 盡量使用繼承,繼承的方法越多,你要寫的代碼量也就越少

2 打開JAVA編譯器的優(yōu)化選項: javac -O 這個選項將刪除掉CLASS文件中的行號,并能把

一些private, static,final的小段方法申明為inline方法調用

3 把公用的代碼提取出來

4 不要初始化很大的數(shù)組,盡管初始化一個數(shù)組在JAVA代碼中只是一行的代碼量,但

編譯后的代碼是一行代碼插入一個數(shù)組的元素,所以如果你有大量的數(shù)據(jù)需要存在數(shù)組

中的話,可以先把這些數(shù)據(jù)放在String中,然后在運行期把字符串解析到數(shù)組中

5 日期類型的對象會占用很大的空間,如果你要存儲大量的日期對象,可以考慮把它存儲為

long型,然后在使用的時候轉換為Date類型

6 類名,方法名和變量名盡量使用簡短的名字,可以考慮使用Hashjava, Jobe, Obfuscate and Jshrink等工具自動完成這個工作

7 將static final類型的變量定義到Interface中去

8 算術運算 能用左移/右移的運算就不要用*和/運算,相同的運算不要運算多次

2. 不要兩次初始化變量

Java通過調用獨特的類構造器默認地初始化變量為一個已知的值。所有的對象被設置成null,integers (byte, short, int, long)被設置成0,float和double設置成0.0,Boolean變量設置成false。這對那些擴展自其它類的類尤其重要,這跟使用一個新的關鍵詞創(chuàng)建一個對象時所有一連串的構造器被自動調用一樣。

3. 在任何可能的地方讓類為Final

標記為final的類不能被擴展。在《核心Java API》中有大量這個技術的例子,諸如java.lang.String。將String類標記為final阻止了開發(fā)者創(chuàng)建他們自己實現(xiàn)的長度方法。

更深入點說,如果類是final的,所有類的方法也是final的。Java編譯器可能會內聯(lián)所有的方法(這依賴于編譯器的實現(xiàn))。在我的測試里,我已經(jīng)看到性能平均增加了50%。

9. 異常在需要拋出的地方拋出,try catch能整合就整合

try {

some.method1(); // Difficult for javac

} catch( method1Exception e ) { // and the JVM runtime

// Handle exception 1 // to optimize this

} // code

try {

some.method2();

} catch( method2Exception e ) {

// Handle exception 2

}

try {

some.method3();

} catch( method3Exception e ) {

// Handle exception 3

}

已下代碼 更容易被編譯器優(yōu)化

try {

some.method1(); // Easier to optimize

some.method2();

some.method3();

} catch( method1Exception e ) {

// Handle exception 1

} catch( method2Exception e ) {

// Handle exception 2

} catch( method3Exception e ) {

// Handle exception 3

}

10. For循環(huán)的優(yōu)化

Replace…

for( int i = 0; i collection.size(); i++ ) {

...

}

with…

for( int i = 0, n = collection.size(); i n; i++ ) {

...

}

5、 在JAVA + ORACLE 的應用系統(tǒng)開發(fā)中,java中內嵌的SQL語句盡量使用大寫的形式,以減輕ORACLE解析器的解析負擔。

10、盡量采用lazy loading 的策略,即在需要的時候才開始創(chuàng)建。

例如: String str = “aaa”;

if(i == 1) {

list.add(str);

}

應替換為:

if(i == 1) {

String str = “aaa”;

list.add(str);

}

12、不要在循環(huán)中使用:

Try {

} catch() {

}

應把其放置在最外層

Java代碼如何優(yōu)化

1. 盡量在合適的場合使用單例

使用單例可以減輕加載的負擔,縮短加載的時間,提高加載的效率,但并不是所有地方都適用于單例,簡單來說,單例主要適用于以下三個方面:

第一,控制資源的使用,通過線程同步來控制資源的并發(fā)訪問;

第二,控制實例的產(chǎn)生,以達到節(jié)約資源的目的;

第三,控制數(shù)據(jù)共享,在不建立直接關聯(lián)的條件下,讓多個不相關的進程或線程之間實現(xiàn)通信。

2. 盡量避免隨意使用靜態(tài)變量

要知道,當某個對象被定義為stataic變量所引用,那么gc通常是不會回收這個對象所占有的內存

3. 盡量避免過多過常的創(chuàng)建Java對象

盡量避免在經(jīng)常調用的方法,循環(huán)中new對象,由于系統(tǒng)不僅要花費時間來創(chuàng)建對象,而且還要花時間對這些對象進行垃圾回收和處理,在我們可以控制的范圍內,最大限度的重用對象,最好能用基本的數(shù)據(jù)類型或數(shù)組來替代對象。

4. 盡量使用final修飾符

帶有final修飾符的類是不可派生的。在Java核心API中,有許多應用final的例子,例如java.lang.String.為String類指定final防止了使用者覆蓋length()方法。另外,如果一個類是final的,則該類所有方法都是final的。Java編譯器會尋找機會內聯(lián)(inline)所有的final方法(這和具體的編譯器實現(xiàn)有關)。此舉能夠使性能平均提高50%.

5. 盡量使用局部變量

調用方法時傳遞的參數(shù)以及在調用中創(chuàng)建的臨時變量都保存在棧(Stack)中,速度較快。其他變量,如靜態(tài)變量、實例變量等,都在堆(Heap)中創(chuàng)建,速度較慢。

6. 盡量處理好包裝類型和基本類型兩者的使用場所

雖然包裝類型和基本類型在使用過程中是可以相互轉換,但它們兩者所產(chǎn)生的內存區(qū)域是完全不同的,基本類型數(shù)據(jù)產(chǎn)生和處理都在棧中處理,包裝類型是對象,是在堆中產(chǎn)生實例。

在集合類對象,有對象方面需要的處理適用包裝類型,其他的處理提倡使用基本類型。

7. 慎用synchronized,盡量減小synchronize的方法

都知道,實現(xiàn)同步是要很大的系統(tǒng)開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制。synchronize方法被調用時,直接會把當前對象鎖 了,在方法執(zhí)行完之前其他線程無法調用當前對象的其他方法。所以synchronize的方法盡量小,并且應盡量使用方法同步代替代碼塊同步。

8. 盡量使用StringBuilder和StringBuffer進行字符串連接

這個就不多講了。

9. 盡量不要使用finalize方法

實際上,將資源清理放在finalize方法中完成是非常不好的選擇,由于GC的工作量很大,尤其是回收Young代內存時,大都會引起應用程序暫停,所以再選擇使用finalize方法進行資源清理,會導致GC負擔更大,程序運行效率更差。

10. 盡量使用基本數(shù)據(jù)類型代替對象

String str = "hello";

上面這種方式會創(chuàng)建一個"hello"字符串,而且JVM的字符緩存池還會緩存這個字符串;

String str = new String("hello");

此時程序除創(chuàng)建字符串外,str所引用的String對象底層還包含一個char[]數(shù)組,這個char[]數(shù)組依次存放了h,e,l,l,o

11. 單線程應盡量使用HashMap、ArrayList

HashTable、Vector等使用了同步機制,降低了性能。

12. 盡量合理的創(chuàng)建HashMap

當你要創(chuàng)建一個比較大的hashMap時,充分利用另一個構造函數(shù)

public HashMap(int initialCapacity, float loadFactor)

避免HashMap多次進行了hash重構,擴容是一件很耗費性能的事,在默認中initialCapacity只有16,而loadFactor是 0.75,需要多大的容量,你最好能準確的估計你所需要的最佳大小,同樣的Hashtable,Vectors也是一樣的道理。

13. 盡量減少對變量的重復計算

并且在循環(huán)中應該避免使用復雜的表達式,在循環(huán)中,循環(huán)條件會被反復計算,如果不使用復雜表達式,而使循環(huán)條件值不變的話,程序將會運行的更快。

14. 盡量避免不必要的創(chuàng)建

15. 盡量在finally塊中釋放資源

程序中使用到的資源應當被釋放,以避免資源泄漏。這最好在finally塊中去做。不管程序執(zhí)行的結果如何,finally塊總是會執(zhí)行的,以確保資源的正確關閉。

16. 盡量使用移位來代替'a/b'的操作

"/"是一個代價很高的操作,使用移位的操作將會更快和更有效

17.盡量使用移位來代替'a*b'的操作

同樣的,對于'*'操作,使用移位的操作將會更快和更有效

18. 盡量確定StringBuffer的容量

StringBuffer 的構造器會創(chuàng)建一個默認大小(通常是16)的字符數(shù)組。在使用中,如果超出這個大小,就會重新分配內存,創(chuàng)建一個更大的數(shù)組,并將原先的數(shù)組復制過來,再 丟棄舊的數(shù)組。在大多數(shù)情況下,你可以在創(chuàng)建 StringBuffer的時候指定大小,這樣就避免了在容量不夠的時候自動增長,以提高性能。

19. 盡量早釋放無用對象的引用

大部分時,方法局部引用變量所引用的對象 會隨著方法結束而變成垃圾,因此,大部分時候程序無需將局部,引用變量顯式設為null.

20. 盡量避免使用二維數(shù)組

二維數(shù)據(jù)占用的內存空間比一維數(shù)組多得多,大概10倍以上。

21. 盡量避免使用split

除非是必須的,否則應該避免使用split,split由于支持正則表達式,所以效率比較低,如果是頻繁的幾十,幾百萬的調用將會耗費大量資源,如果確實需 要頻繁的調用split,可以考慮使用apache的StringUtils.split(string,char),頻繁split的可以緩存結果。

22. ArrayList LinkedList

一 個是線性表,一個是鏈表,一句話,隨機查詢盡量使用ArrayList,ArrayList優(yōu)于LinkedList,LinkedList還要移動指 針,添加刪除的操作LinkedList優(yōu)于ArrayList,ArrayList還要移動數(shù)據(jù),不過這是理論性分析,事實未必如此,重要的是理解好2 者得數(shù)據(jù)結構,對癥下藥。

23. 盡量使用System.arraycopy ()代替通過來循環(huán)復制數(shù)組

System.arraycopy() 要比通過循環(huán)來復制數(shù)組快的多

24. 盡量緩存經(jīng)常使用的對象

盡可能將經(jīng)常使用的對象進行緩存,可以使用數(shù)組,或HashMap的容器來進行緩存,但這種方式可能導致系統(tǒng)占用過多的緩存,性能下降,推薦可以使用一些第三方的開源工具,如EhCache,Oscache進行緩存,他們基本都實現(xiàn)了FIFO/FLU等緩存算法。

25. 盡量避免非常大的內存分配

有時候問題不是由當時的堆狀態(tài)造成的,而是因為分配失敗造成的。分配的內存塊都必須是連續(xù)的,而隨著堆越來越滿,找到較大的連續(xù)塊越來越困難。

26. 慎用異常

當創(chuàng)建一個異常時,需要收集一個棧跟蹤(stack track),這個棧跟蹤用于描述異常是在何處創(chuàng)建的。構建這些棧跟蹤時需要為運行時棧做一份快照,正是這一部分開銷很大。當需要創(chuàng)建一個 Exception 時,JVM 不得不說:先別動,我想就您現(xiàn)在的樣子存一份快照,所以暫時停止入棧和出棧操作。棧跟蹤不只包含運行時棧中的一兩個元素,而是包含這個棧中的每一個元素。

如 果您創(chuàng)建一個 Exception ,就得付出代價。好在捕獲異常開銷不大,因此可以使用 try-catch 將核心內容包起來。從技術上講,您甚至可以隨意地拋出異常,而不用花費很大的代價。招致性能損失的并不是 throw 操作--盡管在沒有預先創(chuàng)建異常的情況下就拋出異常是有點不尋常。真正要花代價的是創(chuàng)建異常。幸運的是,好的編程習慣已教會我們,不應該不管三七二十一就 拋出異常。異常是為異常的情況而設計的,使用時也應該牢記這一原則。

(1)。 用Boolean.valueOf(boolean b)代替new Boolean()

包裝類的內存占用是很恐怖的,它是基本類型內存占用的N倍(N2),同時new一個對象也是性能的消耗。

(2)。 用Integer.valueOf(int i)代替new Integer()

和Boolean類似,java開發(fā)中使用Integer封裝int的場合也非常多,并且通常用int表示的數(shù)值都非常小。SUN SDK中對Integer的實例化進行了優(yōu)化,Integer類緩存了-128到127這256個狀態(tài)的Integer,如果使用 Integer.valueOf(int i),傳入的int范圍正好在此內,就返回靜態(tài)實例。這樣如果我們使用Integer.valueOf代替new Integer的話也將大大降低內存的占用。

(3)。 用StringBuffer的append方法代替"+"進行字符串相加。

這個已經(jīng)被N多人說過N次了,這個就不多說了。

(4)。 避免過深的類層次結構和過深的方法調用。

因為這兩者都是非常占用內存的(特別是方法調用更是堆??臻g的消耗大戶)。

(5)。 變量只有在用到它的時候才定義和實例化。

這是初學者最容易犯的錯,合理的使用變量,并且只有在用到它的時候才定義和實例化,能有效的避免內存空間和執(zhí)行性能上的浪費,從而提高了代碼的效率。

(6)。 避免在循環(huán)體中聲明創(chuàng)建對象,即使該對象占用內存空間不大。

這種情況在我們的實際應用中經(jīng)常遇到,而且我們很容易犯類似的錯誤

采用上面的第二種編寫方式,僅在內存中保存一份對該對象的引用,而不像上面的第一種編寫方式中代碼會在內存中產(chǎn)生大量的對象引用,浪費大量的內存空間,而且增大了垃圾回收的負荷。因此在循環(huán)體中聲明創(chuàng)建對象的編寫方式應該盡量避免。

(7)。 如果if判斷中多個條件用'||'或者''連接,請將出現(xiàn)頻率最高的條件放在表達式最前面。

這個小技巧往往能有效的提高程序的性能,尤其是當if判斷放在循環(huán)體里面時,效果更明顯。

1.JVM管理兩種類型的內存:堆內存(heap),棧內存(stack),堆內在主要用來存儲程序在運行時創(chuàng)建或實例化的對象與變量。而棧內存則是用來存儲程序代碼中聲明為靜態(tài)(static)(或非靜態(tài))的方法。

2.JVM中對象的生命周期,創(chuàng)建階段,應用階段,不可視階段,不可到達階段,可收集階段,終結階段,釋放階段

3.避免在循環(huán)體中創(chuàng)建對象,即使該對象點用內存空間不大。

4.軟引用的主要特點是具有較強的引用功能。只有當內存不夠的時候,才回收這類內存,因此在內存足夠的時候,它們通常不被回收。它可以用于實現(xiàn)一些常用資源的緩存,實現(xiàn)Cache的功能

5.弱引用對象與Soft引用對象最大不同就在于:GC在進行回收時,需要通過算法檢查是否回收Soft引用對象,而對于Weak引用對象,GC總是進行回收。

6.共享靜態(tài)變量存儲空間

7.有時候我們?yōu)榱颂岣呦到y(tǒng)性能,避免重復耗時的操作,希望能夠重用一些創(chuàng)建完成的對象,利用對象池實現(xiàn)。類似JDBC連接池。

8.瞬間值,序列化對象大變量時,如果此大變量又沒有用途,則使用transient聲明,不序列化此變量。同時網(wǎng)絡傳輸中也不傳輸。

9.不要提前創(chuàng)建對象

10 .(1)最基本的建議就是盡早釋放無用對象的引用

A a = new A();

a = null; //當使用對象a之后主動將其設置為空

(2)盡量少用finalize函數(shù)。

(3) 如果需要使用經(jīng)常用到的圖片展,可以使用軟引用。

(4) 注意集合數(shù)據(jù)類型,包括數(shù)組,樹等數(shù)據(jù),這些數(shù)據(jù)結構對GC來說,回收更為復雜,

(5) 盡量避免在類的默認構造器中創(chuàng)建,初始化大量的對象,防止在調用其自類的構造器時造成不必要的內存資源浪費。

(6) 盡量避免強制系統(tǒng)做垃圾內存回收。

(7) 盡量避免顯式申請數(shù)組空間。

(8) 盡量在合適的場景下使用對象池技術以提高系統(tǒng)性能,縮減系統(tǒng)內存開銷。

11.當做數(shù)組拷貝操作時,采用System.arraycopy()方法完成拷貝操作要比采用循環(huán)的辦法完成數(shù)組拷貝操作效率高

12. 盡量避免在循環(huán)體中調用方法,因為方法調用是比較昂貴的。

13. 盡量避免在循環(huán)體中使用try-catch 塊,最好在循環(huán)體外使用try--catch塊以提高系統(tǒng)性能。

14. 在多重循環(huán)中,如果有可能,盡量將最長的循環(huán)放在最內層,最短的循環(huán)放在最外層,以減少循環(huán)層間的變換次數(shù)。

15. 在需要線程安全的情況下,使用List list = Collections.synchronizedList(new ArrayList());

16. 如果預知長度,就設置ArrayList的長度。

17. ArrayList 與 LinkedList 選擇,熟悉底層的實現(xiàn)原理,選擇適當?shù)娜萜鳌?/p>

18. 字符串累加采用StringBuffer.

19. 系統(tǒng)I/O優(yōu)化,采用緩沖和壓縮技術。優(yōu)化性能。

20. 避免在類在構造器的初始化其他類

21 盡量避免在構造中對靜態(tài)變量做賦值操作

22. 不要在類的構造器中創(chuàng)建類的實例

23. 組合優(yōu)化繼承

24. 最好通過Class.forname() 動態(tài)的裝載類

25. JSP優(yōu)化,采用out 對象中的print方法代替println()方法

26 .采用ServletOutputStream 對象代替JSPWriter對象

27. 采用適當?shù)闹党跏蓟痮ut 對象緩沖區(qū)的大小

28. 盡量采用forward()方法重定向新的JSP

29. 利用線程池技術處理客戶請求

30.Servlet優(yōu)化

(1) 通過init()方法來緩存一些靜態(tài)數(shù)據(jù)以提高應用性能。

(2) 用print() 方法取代println()方法。

(3) 用ServletOutputStream 取代 PrintWriter.

(4) 盡量縮小同步代碼數(shù)量

31. 改善Servlet應用性能的方法

(1)不要使用SingleThreadModel

(2)使用線程池ThreadPool

32. EJB優(yōu)化

實體EJB:

(1)實體EJB中常用數(shù)據(jù)緩存與釋放

(2)采用延遲加載的方式裝載關聯(lián)數(shù)據(jù)

(3)盡可能地應用CMP類型實體EJB

(4)直接采用JDBC技術處理大型數(shù)據(jù)

33. 優(yōu)化JDBC連接

(1)設置合適的預取行值

(2)采用連接池技術

(3)全合理應用事務

(4)選擇合適的事務隔離層與及時關閉連接對象

34. PreparedStatemetn只編譯解析一次,而Statement每次都編譯解析。

35. 盡可能地做批處理更新

36. 通過采用合適的getXXX方法提高系統(tǒng)性能

37. 采用設計模式。

Java代碼如何優(yōu)化?從哪些方面入手?分析?

1)盡量指定類、方法的final修飾符。帶有final修飾符的類是不可派生的,Java編譯器會尋找機會內聯(lián)所有的final方法,內聯(lián)對于提升Java運行效率作用重大,此舉能夠使性能平均提高50%。

2)盡量重用對象。由于Java虛擬機不僅要花時間生成對象,以后可能還需要花時間對這些對象進行垃圾回收和處理,因此生成過多的對象將會給程序的性能帶來很大的影響。

3)盡可能使用局部變量。調用方法時傳遞的參數(shù)以及在調用中創(chuàng)建的臨時變量都保存在棧中速度較快,其他變量,如靜態(tài)變量、實例變量等,都在堆中創(chuàng)建速度較慢。

4)慎用異常。異常對性能不利,只要有異常被拋出,Java虛擬機就必須調整調用堆棧,因為在處理過程中創(chuàng)建了一個新的對象。異常只能用于錯誤處理,不應該用來控制程序流程。

5)乘法和除法使用移位操作。用移位操作可以極大地提高性能,因為在計算機底層,對位的操作是最方便、最快的,但是移位操作雖然快,可能會使代碼不太好理解,因此最好加上相應的注釋。

6)盡量使用HashMap、ArrayList、StringBuilder,除非線程安全需要,否則不推薦使用 Hashtable、Vector、StringBuffer,后三者由于使用同步機制而導致了性能開銷。

盡量在合適的場合使用單例。使用單例可以減輕加載的負擔、縮短加載的時間、提高加載的效率,但并不是所有地方都適用于單例。

JSP中存在大量的JAVA代碼好不好?怎樣減少JSP中的JAVA代碼?

JSP中存在大量Java代碼當然不好了,不利于維護和重用。

減少JSP代碼方法:采用后臺處理流程,不在JSP中實現(xiàn)業(yè)務邏輯。

采用MVC架構。

JSP+Servlet+Service層+DAO

JSP+Struts+Service層+DAO

java低代碼開發(fā)平臺有哪些

JNPF低代碼開發(fā)平臺可以以極少量代碼或無代碼的方式開發(fā)各種企業(yè)級管理系統(tǒng),其特點如下:

1. web在線開發(fā)

低代碼開發(fā)平臺是個全Web可視化開發(fā)和運行架構,只要在web端網(wǎng)頁就能開發(fā),不需要安裝配置復雜的本地開發(fā)環(huán)境;

2. 代碼生成器

依托代碼生成器,開發(fā)人員大大減少了代碼編輯量,并且生成的代碼還可下載拷貝應用,可根據(jù)需求進行個性化修改;

3. 工作流引擎

工作流引擎可以輕松快捷的搭建業(yè)務流程管理系統(tǒng)和協(xié)同交互管理體系,可隨時按需更改流程邏輯以適應新需求;

4. 流程設計器

流程設計器集成了表單設計器和流程引擎,并支持線性流程、父子流程、同步分合流、異步分合流程,全部實現(xiàn)可視化設計;

5. 全源碼交付

低代碼開發(fā)平臺提供商業(yè)化的全源碼交付,可進行二次個性化開發(fā),減少了代碼編寫,簡化了開發(fā)流程,提升了開發(fā)效率;

6. 更新升級快速

如果需求發(fā)生變化,用戶只需通過web端網(wǎng)頁登錄開發(fā)賬號,調整相應的功能并發(fā)布即可,整個過程可能只需要幾分鐘便可完成;

7. 數(shù)據(jù)管理強大

低代碼開發(fā)平臺的數(shù)據(jù)處理功能十分強大,可自動生成各種報表,還可以以大屏的方式直觀的呈現(xiàn)出實時的動態(tài)數(shù)據(jù);

8. 縮減開發(fā)成本

傳統(tǒng)的編程開發(fā)模式需要許多人來共同協(xié)作研發(fā),現(xiàn)在運用低代碼開發(fā)平臺只需要兩三個甚至一個人便可完成開發(fā)工作;

9. 部署方式靈活

平臺的部署方式十分多樣化,可實現(xiàn)公有云和私有云部署,也可進行本地化部署,以滿足企業(yè)多變的差異化需求;

10. 快速開發(fā)SaaS

平臺可以輕松快速地開發(fā)ERP、CRM、HRM、BPM、OA、財務管理等各類SaaS管理系統(tǒng)和業(yè)務管理系統(tǒng),助力企業(yè)效益提升;

這便是JNPF低代碼開發(fā)平臺的主要特點和優(yōu)勢,其大大優(yōu)于第三方定制開發(fā)以及企業(yè)自主探索開發(fā)等幾種傳統(tǒng)的開發(fā)方式。運用JNPF低代碼開發(fā)平臺,開發(fā)者可以高效快速的開發(fā)各種企業(yè)管理系統(tǒng),并還可以進行各種子系統(tǒng)、子平臺的開發(fā)拓展,以滿足企業(yè)各種復雜的管理運營需求,同時系統(tǒng)的更新升級也十分敏捷方便。

網(wǎng)頁名稱:java代碼量消減,減少代碼量
轉載源于:http://www.muchs.cn/article28/hssijp.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設計公司、云服務器、軟件開發(fā)、關鍵詞優(yōu)化、商城網(wǎng)站、網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

綿陽服務器托管