摘要:原文出自本文總結了程序員常犯的個錯誤。可以看看為什么在中被設計成不可變父類和子類的構造函數以上這段代碼出現編譯錯誤,因為默認的父類構造函數未定義。如果程序員定義構造函數,編譯器將不插入默認的無參數構造函數。
原文出自:http://www.programcreek.com/2014/05/top-10-mistakes-java-developers-make/
本文總結了Java程序員常犯的10個錯誤。
1. 把Array轉化成ArrayList把Array轉化成ArrayList,程序員經常用以下方法:
List
Arrays.asList() 實際上返回一個ArrayList,但是這個ArrayList是Arrays的一個內部私有類,而不是java.util.ArrayList類。這個私有類java.util.Arrays.ArrayList有set(), get(), contains()方法,但是不能夠添加新的元素。它的大小是固定的。如果你想要一個java.util.ArrayList,正確的方法是:
ArrayList
java.util.ArrayList的構造函數可以接受一個集合類型。java.util.Arrays.ArrayList也繼承了集合類型,所以可以作用參數使用。
開發人員經常做的是:
Set
return set.contains(targetValue);
這個代碼是工作的,但沒有沒有效率。把列表轉換成set沒有必要,需要額外的時間。正確的方法是:
Arrays.asList(arr).contains(targetValue);
或者,一個簡單的loop:
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
第一種比第二種更具有可讀性。
考慮下面的代碼,迭代過程中刪除元素:
ArrayList
for (int i = 0; i < list.size(); i++) {
list.remove(i);
}
System.out.println(list);
這段代碼的輸出是:
[b, d]
這個方法有一個嚴重的問題。當元素被移除,該列表的大小縮減,元素索引也隨之發生了變化。所以,如果你想通過使用索引來刪除一個循環內的多個元素,就會導致錯誤的結果。
你可能猜到可以使用iterator來刪除循環中的元素。在Java中的foreach循環的工作原理就像一個iterator。 但是在這里也會發生錯誤。請看下面的代碼:
ArrayList
for (String s : list) {
if (s.equals("a"))
list.remove(s);
}
上面的foreach loop代碼會拋出一個異常ConcurrentModificationException. 但是下面這段代碼不會。
ArrayList
Iterator
while (iter.hasNext()) {
String s = iter.next();
if (s.equals("a")) { iter.remove(); }
}
通過分析ArrayList.iterator()的原代碼,我們可以發現next()方法必須要在remove()方法前被調用。在foreach loop中,編譯器產生的代碼會先調用next()方法,從而產生異常ConcurrentModificationException。請查看ArrayList.iterator()的原代碼。
按照算法慣例,Hashtable是數據結構的名稱。但在Java中,數據結構的名稱是HashMap。Hashtable是同步的版本。所以很多時候你并不需要Hashtable,而是HashMap。 這兩篇文章詳細介紹了各種Map的區別和常見的問題: HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap, Map常見10大問題,
5.使用原始類型Collection在Java中,原始類型和無界通配符類型很容易混在一起。以Set為例,Set是原始類型,而Set>是無界通配符類型。
考慮下面的代碼,它使用原始類型的List作為參數:
public static void add(List list, Object o){
list.add(o);
}
public static void main(String[] args){
List
很多時候,開發者使用public修飾字段。這樣做的好處是很容易通過直接引用來獲取字段的值,但是這是一個非常糟糕的設計。經驗法則是“給成員的訪問級別盡可能低”。可以查看Java4種不同的訪問級別public, default, protected, and private。
7. ArrayList 與 LinkedList當開發人員不知道ArrayList和LinkedList的區別的時候,他們經常使用的是ArrayList,可能因為它看起來面熟。但是ArrayList和LinkedList之間有巨大的性能差異。 簡單來說如果有大量的添加/刪除操作,而沒有很多隨機存取操作,LinkedList的應該是首選。可以查看ArrayList與LinkedList了解它們之間更多的區別。
8.可變性與不變性不可變對象有很多優點,如簡單性,安全性等。但是它需要為每個不同的值創造一個多帶帶的對象,對象太多可能會導致垃圾回收的成本高。所以可變和不可變之間進行選擇時應該有一個平衡。
一般情況下,使用可變對象,以避免產生過多的中間對象。一個經典的例子是串聯了大量的字符串。如果使用的是不可變的字符串String,會產生很多可以垃圾回收的對象。這樣既浪費時間也浪費CPU的運算能力,使用可變對象是正確的解決方案(如StringBuilder)。
String result="";
for(String s: arr){
result = result + s;
}
另外一些情況,可變對象剛更加合適可取。例如排序(Collections.sort())。如果Collection是不可變的,排序方法每次將會返回一個新的Collection,這樣會極其浪費資源。 可以看看為什么在Java中String被設計成不可變?
以上這段代碼出現編譯錯誤,因為默認的父類構造函數未定義。在Java中,如果一個類沒有定義構造函數,編譯器會默認插入一個默認的無參數構造函數。如果程序員定義構造函數,編譯器將不插入默認的無參數構造函數。上面的代碼由于自定義了有參數的構造函數,編譯器不再插入無參數的構造函數。子類的構造函數,無論是有參數或無參數,都將調用父類無參構造函數。當子類需要父類的無參數構造函數的時候,就發生了錯誤。
解決這個問題,可以1)增加一個父類構造函數
public Super(){
System.out.println("Super");
}
,或2)刪除自定義的父類構造函數,或3)添加super(value)到子類構造函數。更多請查看父類和子類的構造函數。
字符串可以通過兩種方式創建:
//1. use double quotes
String x = "abc";
//2. use constructor
String y = new String("abc");
這兩者有什么區別呢? 下面的例子可以提供一個快速的答案:
String a = "abcd";
String b = "abcd";
System.out.println(a == b); // True
System.out.println(a.equals(b)); // True
String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d); // False
System.out.println(c.equals(d)); // True
關于它們是如何分配內存的更多信息,請查看創建Java字符串使用“”或構造函數?
小結
以上是我根據GitHub上的開源項目,Stack Overflow上的問題,和谷歌熱門搜索詞所做的總結。雖然它們不是準確的top 10,但很常見的。如果你有不同的觀點或者指出更常見的錯誤,請留言。我也會更新這個列表。非常感謝。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64162.html
摘要:對于程序員來說,更意味著代碼的組織,工作成員之間的協作方式。我常犯的一個錯誤是直接在或分支上直接,而團隊是不允許這樣做的。 先介紹下背景,博主由運營轉行前端,入職一個月,完成了一個相對較大的模塊。由于基礎相對薄弱,犯下了不少錯誤,故想記錄下來警醒自己和分享各位。 前端技術棧是 ES6 + backbone + react + antdUI,后端使用的 Ruby on Rails。 1....
摘要:對于程序員來說,更意味著代碼的組織,工作成員之間的協作方式。我常犯的一個錯誤是直接在或分支上直接,而團隊是不允許這樣做的。 先介紹下背景,博主由運營轉行前端,入職一個月,完成了一個相對較大的模塊。由于基礎相對薄弱,犯下了不少錯誤,故想記錄下來警醒自己和分享各位。 前端技術棧是 ES6 + backbone + react + antdUI,后端使用的 Ruby on Rails。 1....
摘要:對于程序員來說,更意味著代碼的組織,工作成員之間的協作方式。我常犯的一個錯誤是直接在或分支上直接,而團隊是不允許這樣做的。 先介紹下背景,博主由運營轉行前端,入職一個月,完成了一個相對較大的模塊。由于基礎相對薄弱,犯下了不少錯誤,故想記錄下來警醒自己和分享各位。 前端技術棧是 ES6 + backbone + react + antdUI,后端使用的 Ruby on Rails。 1....
摘要:下面列舉了我曾經犯過的最嚴重的個相關的錯誤有些同樣也反映在其他語言數據庫的使用上。用服務器端的驗證每個字符串,不要寄希望與。登錄的時候,必須以一個為依據查找正確的。和是最強有力的競爭者這個兩者都是開源的,而且都沒有被公司收購。 對于大多數web應用來說,數據庫都是一個十分基礎性的部分。如果你在使用PHP,那么你很可能也在使用MySQL—LAMP系列中舉足輕重的一份子。對于很多新手們來說...
閱讀 2521·2023-04-26 02:57
閱讀 1403·2023-04-25 21:40
閱讀 2155·2021-11-24 09:39
閱讀 3557·2021-08-30 09:49
閱讀 760·2019-08-30 15:54
閱讀 1166·2019-08-30 15:52
閱讀 2068·2019-08-30 15:44
閱讀 1274·2019-08-28 18:27