Javaプログラマがよく犯している10のエラー

4881 ワード

原文の出典:http://www.programcreek.com/2014/05/top-10-mistakes-java-developers-make/
本論文はJavaプログラマがよく犯している10のエラーをまとめたものである。
1.ArayをArayListに変換する
ArayをArayListに変換するには、プログラマはよく以下の方法を使います。
List list=Arays.asList(arr)Arays.asList()は実際にArayListに戻るが、このArayListはAraysの内部プライベートクラスであり、java.util.ArayListクラスではない。このプライベートクラスはjava.util.Arays.ArayListにset()、get()、contains()の方法がありますが、新しい要素を追加することはできません。サイズは固定です。java.util.ArayListが欲しいなら、正しい方法は:
ArayList arrayList=new ArayList(Arays.asList);java.util.ArayListの構造関数は、1つのセットタイプを受け入れることができる。java.util.Arays.ArayListも集合タイプを継承していますので、作用パラメータは使用できます。
2.配列に値が含まれているかどうかを確認する
開発者がよくやっているのは:
Set set=new HashSet(Arays.asList);return set.co ntains;このコードは仕事ですが、効率がありません。リストをsetに変換する必要はありません。時間がかかります。正しい方法は:
Arays.asList.contains;または、簡単なloop:
for(String s:arr){if(s.equals)return true;}return false;第一は、第二よりも可読性を有する。
3.サイクル中にリスト要素を削除する
以下のコードを考慮して、反復中に要素を削除します。
ArayList=new ArayList(Arays.asList(「a」「b」「c」「d」));for(int i=0;i<list.size();i++){list.remove(i)}System.out.print ln(list);このコードの出力は:
[b,d]この方法には深刻な問題がある。要素が削除されると、リストのサイズが縮小され、要素インデックスも変化します。したがって、インデックスを使って、ループ内の複数の要素を削除すると、エラーの結果になります。
iteratorを使って循環中の要素を削除できると推測できます。Javaでのforeachサイクルの動作原理はiteratorのようです。しかし、ここでも間違いが発生します。下のコードを見てください。
ArayList=new ArayList(Arays.asList(「a」「b」「c」「d」));
for(Stering s:list){if(s.equals(a)))list.remove(s)}上のforeach loopコードは異常Conccurrent Modification Exceptionを投げますが、下のこのコードはできません。
ArayList=new ArayList(Arays.asList(「a」「b」「c」「d」));Iterator iter=list.iterator()while(iter.has Next(){String=iter.next();
if (s.equals("a")) {
    iter.remove();
}
}ArayList.iterator()のソースコードを分析することにより、next()方法はremove()方法の前に呼び出さなければならないことが分かります。foreach loopでは、コンパイラから発生したコードがnext()メソッドを呼び出し、異常ConcerentModificationExceptionが発生します。ArayList.iterator()のソースコードを確認してください。
4.HashtableとHashMap
アルゴリズムの慣例によれば、Hashtableはデータ構造の名称である。しかし、Javaでは、データ構造の名前はHashMapです。Hashtableは同期版です。ですから、Hashtableではなく、HashMapが必要です。この二つの文章は各Mapの違いとよくある問題を詳しく紹介しています。HashMap vs.TreeMap vs.hashtable vs.LinkdhashMap,Mapによくある10の問題です。
5.オリジナルタイプのコレクションを使う
Javaでは、オリジナルタイプとワイルドカードタイプが混在しやすいです。SetはSetを例にとって元のタイプであり、Setはワイルドカードタイプである。以下のコードを考慮して、元のタイプのListをパラメータとして使用します。public static void add(List list、Object o){list.add(o);}public static void main(String[]args){List=new ArayList();add(list,10)))String.String.String.ArayList.mastring.maring.Maring.Maring.maring.Maring.Maring.Maring.Maring.Maring.Maring.Maring.Maring.Maringjava.lang.CastException:java.lang.Integer cannot be cast to java.lang.String at...オリジナルタイプのCollectionを使うのは危険です。オリジナルタイプのCollectionがタイプ検査をスキップするからです。また、Set、Set>とSetの間には大きな違いがあります。もっと多くのことを知っています。オリジナルのタイプvs.ワイルドカードの種類とタイプを確認してください。
6.アクセスレベル
多くの場合、開発者はフィールドをPublicで修飾します。このようにする利点は、直接参照によってフィールドの値を取得することが容易であるが、これは非常に悪い設計である。経験則は「メンバーへのアクセスレベルができるだけ低い」ということです。Java 4種類の異なるアクセスレベルpublic、default、protected、and prvateを見ることができます。
7.ArayListとLinked List
ArayListとLinkdListの違いを知らない開発者がよく使うのはArayListで、見覚えがあるからかもしれません。しかし、ArayListとLinkdListの間には大きな性能の差があります。簡単に言えば、大量の追加・削除操作があれば、ランダムアクセス操作が多くなく、Linked Listが優先されるべきです。ArayListとLinkdListはそれらの違いをもっと知ることができます。
8.可変性と不変性
可変ではないオブジェクトには、簡単性、安全性など、多くの利点があります。しかし、それぞれの価値のために個別のオブジェクトを作成する必要があります。対象が多すぎると、ゴミの回収コストが高くなります。だから可変と不可変の間で選択する時はバランスが必要です。
一般的には、中間オブジェクトの過剰発生を避けるために、可変オブジェクトを使用します。古典的な例は多数の文字列を直列にしたものである。変な文字列Stringを使うと、ゴミを回収できる対象がたくさん発生します。このように時間を無駄にしたり、CPUの演算能力を無駄にしたり、可変オブジェクトを使ったりするのは正しい解決策です。
Stering result="";for(String s:arr){result=result+s}他の場合は、可変オブジェクトがより適切であることが望ましい。例えば、並べ替え(Collection.sort())。もしCollectionが可変でないなら、順序付け方法は毎回新しいCollectionを返します。これは資源を浪費します。JavaではなぜStringが可変されないように設計されているのか見てもいいです。
9.親と子の構造関数
以上のコードはコンパイルエラーが発生しました。標準の親構造関数が定義されていません。Javaでは、クラスにコンストラクタが定義されていない場合、コンパイラはデフォルトで引数なしのコンストラクタを挿入します。プログラマがコンストラクタを定義すると、コンパイラはデフォルトのパラメトリックレスコンストラクタを挿入しません。上のコードはパラメータのあるコンストラクタをカスタマイズしたため、コンパイラはパラメータのないコンストラクタを挿入しなくなりました。サブクラスのコンストラクタは、パラメータがあるかどうかにかかわらず、親の無参画構造関数を呼び出します。親類の無パラメータ構造関数がサブクラスに必要となると、エラーが発生します。
この問題を解決すれば、1)父の構造関数を追加できます。
public Super(){System.out.println("Super")}、または2)カスタムの親構造関数を削除し、または3)サブクラス構成関数にsuper(value)を追加します。さらに、親と子の構造関数を確認してください。
10.「」とコントロ?
文字列は2つの方法で作成できます。
//1.use double quot tes 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のオープンソースプロジェクトに基づいて、Stock Overflow上の問題とGoogleの人気検索語のまとめです。正確なtop 10ではないが、よく見られます。もしあなたが違った見方をしたり、もっとよくある間違いを指摘したりしたら、メッセージを残してください。私もこのリストを更新します。本当にありがとうございます。