1、 盡量指定類的final修飾符 帶有final修飾符的類是不可派生的。
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供邕寧網(wǎng)站建設、邕寧做網(wǎng)站、邕寧網(wǎng)站設計、邕寧網(wǎng)站制作等企業(yè)網(wǎng)站建設、網(wǎng)頁設計與制作、邕寧企業(yè)網(wǎng)站模板建站服務,十余年邕寧做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡服務。
在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代碼之于java程序員而言就是左膀右臂,java代碼寫的好的java程序員明顯更是企業(yè)的歡迎,一個優(yōu)秀的java程序員的考核標準之一也是看他的編程水平。
其實有的java程序員java代碼會受到大家的追捧,是因為他在寫代碼時注意的細節(jié)往往多于那些不怎么關注java代碼編程細節(jié)的程序員,俗話說:“細節(jié)決定成敗”,那么如何寫出好的java代碼呢?IT培訓介紹一起來討論下:
1.重視注釋
有的java程序員在寫代碼時,從來沒有想過要在java代碼后加上相關的注釋,甚至是上萬行的代碼也沒有想過加上注釋,這就存在很大的問題,不說你的代碼會跟其他人分享討論,就你自己回顧你是怎么寫好這篇代碼的,你也是半天無法理出頭緒,這就為維護和修改等等工作添加了很大的麻煩。所以,要想寫出好的java代碼,一定從簡短的java代碼編寫開始注重在java代碼后面加上相應的注釋,養(yǎng)成良好的習慣。
2.重視排版整潔
看很多java程序員的排版總覺得在欣賞一幅藝術品,但是看到一些java程序員的排版卻總覺得無力吐槽。同樣是編寫代碼,但是給人的視覺體驗是相當?shù)牟煌斎缓玫膉ava代碼給人的享受也是美的,所以要想寫出好的代碼,一定要重視排版整潔。
3.注重命名規(guī)則
現(xiàn)在在一個團隊開發(fā)中,都會提前定制一個統(tǒng)一的命名規(guī)則,這樣利于提高工作效益。但是很多java程序員是缺乏這個意識的,每次敲代碼,更喜歡按照自己慣常的方式老命名模塊、函數(shù),這樣是方便了自己,但是忽視團隊協(xié)作,所以在日常工作中,特別是團隊工作中一定要重視命名規(guī)則。
4.養(yǎng)成備份習慣
備份的重要性不用小編強調,相必你也知道。但是有的java程序員就是沒有養(yǎng)成這樣的好習慣,每次敲完代碼就不記得隨手保存,每次等到除了事故,比如電腦出了故障,辛辛苦苦敲打的java代碼沒保存找不回來的情況下就開始懊惱,與其這樣還不如在一開始就養(yǎng)成良好的備份習慣,這樣也方便自己日后查找利用。
不管什么項目的電商項目,現(xiàn)在都是調用統(tǒng)一支付接口,沒誰自己做支付接口的 不管是網(wǎng)頁、安卓還是ios,都可以找到
因為%左右操作數(shù)都必須是整數(shù),但是前面的(11+3*8)/4得出結果不是整數(shù),所以要先轉換
int a=( (int)( (11+3*8)/4 ) )%3
盡量使用完整的英文描述符,采用適用于相關領域的術語,采用大小寫混合使名字可讀。
JAVA代碼規(guī)范:
(1)類名首字母應該大寫。字段、方法以及對象(句柄)的首字母應小寫。對于所有標識符,其中包含的所有單詞都應緊靠在一起,而且大寫中間單詞的首字母。例如:
ThisIsAClassName
thisIsMethodOrFieldName
若在定義中出現(xiàn)了常數(shù)初始化字符,則大寫static final基本類型標識符中的所有字母。這樣便可標志出它們屬于編譯期的常數(shù)。Java包(Package)屬于一種特殊情況:它們全都是小寫字母,即便中間的單詞亦是如此。對于域名擴展名稱,如com,org,net或者edu等,全部都應小寫(這也是Java1.1和Java1.2的區(qū)別之一)。
(2)為了常規(guī)用途而創(chuàng)建一個類時,請采取"經(jīng)典形式",并包含對下述元素的定義:equals()
hashCode()
toString()
clone()(implement Cloneable)
implement Serializable
(3)對于自己創(chuàng)建的每一個類,都考慮置入一個main(),其中包含了用于測試那個類的代碼。為使用一個項目中的類,我們沒必要刪除測試代碼。若進行了任何形式的改動,可方便地返回測試。這些代碼也可作為如何使用類的一個示例使用。
(4)應將方法設計成簡要的、功能性單元,用它描述和實現(xiàn)一個不連續(xù)的類接口部分。理想情況下,方法應簡明扼要。若長度很大,可考慮通過某種方式將其分割成較短的幾個方法。這樣做也便于類內代碼的重復使用(有些時候,方法必須非常大,但它們仍應只做同樣的一件事情)。
(5)設計一個類時,請設身處地為客戶程序員考慮一下(類的使用方法應該是非常明確的)。然后,再設身處地為管理代碼的人考慮一下(預計有可能進行哪些形式的修改,想想用什么方法可把它們變得更簡單)。
(6)使類盡可能短小精悍,而且只解決一個特定的問題。下面是對類設計的一些建議:
一個復雜的開關語句:考慮采用"多形"機制
數(shù)量眾多的方法涉及到類型差別極大的操作:考慮用幾個類來分別實現(xiàn)
許多成員變量在特征上有很大的差別:考慮使用幾個類
(7)讓一切東西都盡可能地"私有"-private??墒箮斓哪骋徊糠?公共化"(一個方法、類或者一個字段等等),就永遠不能把它拿出。若強行拿出,就可能破壞其他人現(xiàn)有的代碼,使他們不得不重新編寫和設計。若只公布自己必須公布的,就可放心大膽地改變其他任何東西。在多線程環(huán)境中,隱私是特別重要的一個因素-只有private字段才能在非同步使用的情況下受到保護。
(8)謹惕"巨大對象綜合癥。對一些習慣于順序編程思維、且初涉OOP領域的新手,往往喜歡先寫一個順序執(zhí)行的程序,再把它嵌入一個或兩個巨大的對象里。根據(jù)編程原理,對象表達的應該是應用程序的概念。
網(wǎng)頁標題:java代碼滿減怎樣寫,java中的減法
網(wǎng)頁URL:http://sd-ha.com/article10/dsippgo.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導航、云服務器、搜索引擎優(yōu)化、定制開發(fā)、網(wǎng)站設計公司、品牌網(wǎng)站建設
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)