この5つの最も犯しやすいJavaエラーを見て、あなたは犯しましたか?

4370 ワード

人は聖賢でなければ,だれが過ちを犯すことができるのか.Java言語は簡単なプログラミング言語であり、C++の進化に基づいて、多くのC++の複雑な特性を排除していると言われていますが、Javaプログラマーが間違いを犯さないことは保証されていません.では、多くのJavaプログラマーにとって、最も犯しやすいいくつかの間違いは何でしょうか.次に、これらの間違いもあなたがよく犯しているかどうかを見てみましょう.
1、車輪を繰り返す明らかな間違いはJavaプログラマーがすでに存在する大量のライブラリを習慣的に無視することである.車輪を作ることを決めた間、既存のライブラリがあるかどうかを探してみることをお勧めします.例えばログにはlogback,新log 4 j,ネットワークにはNettyまたはAkkaがある.Java 8に組み込まれたJoda-timeのようなライブラリが徐々に標準化されています.次は私の前のプロジェクトの個人的な経験です.HTMLのエスケープに使用されるコードの一部は、開発が独自に完了しています.このコードは長年正常に動作していたが、再びユーザー入力に遭遇し、コードはデッドサイクルに陥った.このユーザーはアプリケーションが反応していないことに気づいて、もう一度入力し直しました.サーバーはこのデッドサイクルで切れました.Google Guavaプロジェクトが提供するHtmlEscaperのような既存のHTMLエスケープツールを使用すると、この深刻な問題は発生しない可能性があります.また、現在市販されているほとんどのオープンソースライブラリは、背後にチームやコミュニティがサポートしており、このようなエラーは、タイムリーに修復されます.2、Switch-Caseでbreakを誤って使用するのは気まずい問題ですが、実際の開発ではよく発生します.滝の特性はswitch文で非常に役立つ場合がありますが、必要なbreakキーワードの欠落は、災害的な結果をもたらす場合があります.たとえば次のコードではcase 0にbreakキーを置くのを忘れた場合、コードは下に実行され続けます.Zeroの後にOne:public static void switch CasePrimer(){int caseIndex=0;switch(caseIndex){case 0:System.out.println("Zero");case 1:System.out.println("One");break;case 2:System.out.println("Two");break;default:System.out.println("Default");}
最良の解決策は、マルチステートを使用し、異なる処理コードをサブクラスに配置することです.もちろん、このようなエラーは、FindBugsやPMDのようなツールでチェックすることもできます.3、リソースを解放するのを忘れたファイルを開くか、ネットワーク接続を確立すると、リソースを閉じることを覚えておくことが重要です.また、このようなリソースの使用中にエラーが発生した場合、異常処理中にも対応するクローズ操作が必要であることを覚えておいてください.FileInputStreamオブジェクトがGCにいるときにJavaターミネータ(finalizer)がclose()メソッドを自動的に呼び出すと言う人もいるかもしれませんが、GCがいつ始まるかは予知できないので、GCを実行する前にどのくらいのリソースがタイムリーに閉じられないかは予知できません.このような状況を避けるために、Java 7が発売したtry-with-resources構文は、開発ごとに使用する価値があります.private static void printFileJava7() throws IOException {try(FileInputStream input = new FileInputStream("file.txt")) {int data = input.read();while(data != -1){System.out.print((char) data);data = input.read();}}}
try-with-resources構文は、AutoClosableインタフェースを実装したすべてのクラスに適用されます.各リソースのタイムリーな閉鎖を保証します.4、メモリ漏洩Javaは自動メモリ管理を使用するため、ほとんどの時間、メモリの割り当てと解放に関心を持っていませんが、Java開発者がメモリを無視する必要はありません.Javaアプリケーションでは、メモリの問題もよく発生します.オブジェクトが参照されていない場合、オブジェクトは解放されますが、メモリ漏洩の問題は発生しません.Javaでは、メモリ漏洩の原因はたくさんありますが、最も起こりやすいのは、GCがスタックメモリを回収するときに、1つのオブジェクトが他のオブジェクトに参照されている場合、このオブジェクト空間は回収されません.例を挙げると、クラスに静的フィールドが1つのセットに参照されている場合、もし私たちが手動でこの集合を使用して完了した後にnullに設定していないならば、この集合とこの集合の中のオブジェクトは、クラス静的フィールドがGCされないため、永遠に回収されません.例えば、メモリの漏洩の原因として、オブジェクトのグループが互いに相手を引用していること、つまり私たちがよく言っている循環参照があります.循環参照のため、GCはこれらの相互参照のオブジェクトが存続する必要があるかどうかを確定できません.もう1つのケースは、JNIを使用しているときの非スタックメモリの漏洩です.典型的なメモリ漏洩例:f i n a l S h e d u l edExecutorService scheduledExecutorService=Executors.newScheduledThreadPool(1);final Deque numbers = new LinkedBlockingDeque<>();final BigDecimal divisor = new BigDecimal(51);
scheduledExecutorService.scheduleAtFixedRate(() -> {BigDecimal number = numbers.peekLast();if (number != null && number.remainder(divisor).byteValue() == 0) {System.out.println("Number: "+ number);System.out.println("Deque size: "+ numbers.size());}}, 10, 10, TimeUnit.MILLISECONDS);
scheduledExecutorService.scheduleAtFixedRate(() -> {
    numbers.add(new BigDecimal(System.currentTimeMillis()));
}, 10, 10, TimeUnit.MILLISECONDS);

try {scheduledExecutorService.awaitTermination(1, TimeUnit.DAYS);} catch (InterruptedException e) {e.printStackTrace();}
上記の例では、2つのタイミングタスクを作成しました.最初のタイミングタスクは、dequeから最後の数字「numbers」を取得し、この数字が51で割り切れると、その数字とdequeの大きさが印刷されると判断する.2番目のタイミングタスクは、dequeにデータを絶えず追加します.両方のタスクは10 ms間隔で実行されます.このコードが実行されると、dequeのデータがスタック全体を占めるまでdequeのサイズが増加し続けることがわかります.このような状況を阻止するために、peekLastメソッドの代わりにpollLastメソッドを使用することができます.pollLastメソッドは最後の要素を手に入れた後、この要素をdequeから除去するからです.5、ごみデータを過度に生成ごみデータを過度に生成するという意味で、プログラム実行中に短い宣言周期を大量に生成する対象である.今回はGCが頻繁に実行され,メモリからスペースが回収され,GCの実行にはスタックスキャンが必要となり,システムの性能に大きな影響を及ぼす.次の例は、String oneMillionHello=""";for (int i = 0; i < 1000000; i++) {oneMillionHello = oneMillionHello + "Hello!";}System.out.println(oneMillionHello.substring(0, 6));
Javaでは文字列は可変ではないので、ループごとに新しい文字列オブジェクトが作成されます.このコードを改善するために、StringBuilderの代わりにStringBuilder oneMillionHelloSB=new StringBuilder()を使用することができます.for (int i = 0; i < 1000000; i++) {oneMillionHelloSB.append("Hello!");}System.out.println(oneMillionHelloSB.toString().substring(0, 6));
2番目のバージョンのコードは、実行時に多くのパフォーマンスを向上させます.今回の干物分かち合いはここで終わりです!より多くの乾物や無料のリソースを取得するには、毎週の更新に注目してください.私と一緒に階段を上がって変なことをします!