私は行く、あなたはまだのtry-catch-最終的に使用する必要があります

前に私が読んブラザー、あなたの事、私は切り替えるように行ってきましたああ別のものを書くことではない、ので、面白いです何も特別な記事をもっとああ読んだ後に言いたいこと?Java構文の使用は13ですが、古いバージョンでは非常に友好的ではありません。しかし、誰がJava 6の中に生きているようなJava 8は、ビーチで射殺ようにJavaは、再度のメジャーアップデートをそれをしないことを保証することができます。Javaの8は、私はかなりあなたは、兄弟、それらの反対の声を気にしない、香りですが、遅かれ早かれ、アップグレードしたいです。

これは、特に、先週は私に情報を与えるためにアリスの読者である、私は本当に感動しました。確かに、最後はレバレッジの量を読んで、「私はに行ってきました」、15000句は一日中読んCSDN、を含む、いくつかの大規模な復刻しました。しかし、そのような種類の批判の音も多くある「私はあなたが、どんな新しいスタントを持っているJavaの13を使用することを期待していなかったと思いました」。

しかし、私の心は素晴らしいされています。それらを数えるように私は密なオーバーヘッドなどの日から最初の記事、回数ヘアスプレーの量を書きました。私は新しいものを持って来るに彼らの努力を倍加することを決めたので、「私は行きます。」

当社はまた、仕事への復帰であるため、リモートレビューは、しないでください。コードのレビューはまだエイミーのある、彼はコードのほとんどを書いた厳格な注釈が所定の位置にもある一方で、非常に美しいです、それは私はとても幸せ。私が見たとき、しかし、彼は役に立たないしてみてください - と - リソースにはまだ助けが、呪いができないとき、:「!私はこする、エイミー、あなたああは実際にはまだのtry-catch-最後に使用します」

王はそれで書かれたコードを見てください。

public class Trycatchfinally {
    public static void main(String[] args) {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader("/牛逼.txt"));
            String str = null;
            while ((str =br.readLine()) != null) {
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
复制代码

ねえ、私は、ファイル名がいる場合は特に、完璧なああ、のtry-catch-最後に使用されているコードは非常に良好であったと感じ牛逼.txt非常に明るいです。書き込みのコメントは、このコードがやっている理解することができないでください:tryブロック内のファイルの内容を読み、コンソールに出力行ずつ。ファイルが見つからないか、エラーが読んでキャッチで誤ったスタック情報の書き込み、キャプチャおよび印刷するIOを発生した場合。最後に、近いBufferedReaderのは、最終的にオブジェクトバッファリング文字読取装置は、効果的なパフォーマンスが閉じられていないリソースの可用性の重大な結果に終止符を打ちます。

Javaの7の前に、のtry-catch-最後に、実際のリソースを確保するための最良の方法は、速やかにプログラムが例外をスローするかどうか、閉じられます。

しかし、その後、経験豊富な読者は、このコードの上から2つの重大な問題があります:

1)ファイル名「に退行.txtのは」中国、合格する必要が含まれてjava.net.URLDecoderクラスのdecode()実行時にその脱出の方法、そうでない場合は、このコードは間違いなく例外が見つかりませんファイルをスローしたいと思います。

2)あなたに直接通じている場合new FileReader("牛逼.txt")、同じレベルのディレクトリでのsrcニーズやプロジェクト「の.txt回帰し、」FileReaderのオブジェクトを作成するために、またはファイルにも例外がスローされます見つけることができません。しかし、ほとんどのケースでは、(設定)ファイルは、リソースディレクトリの下に置かれる簡単classesディレクトリ内のファイルが表示されますをコンパイルするために、以下を参照してください。

この2つの問題を解決するために、我々は、コードを最適化する必要があります。

public class TrycatchfinallyDecoder {
    public static void main(String[] args) {
        BufferedReader br = null;
        try {
            String path = TrycatchfinallyDecoder.class.getResource("/牛逼.txt").getFile();
            String decodePath = URLDecoder.decode(path,"utf-8");
            br = new BufferedReader(new FileReader(decodePath));

            String str = null;
            while ((str =br.readLine()) != null) {
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
复制代码

コンソールへの正しい出力は、このコードを実行し、ファイルの内容をプログラムすることができます。あなたは憧れの「クリーン」の単語の上にある場合でも、このコードは、ビール腹の12本のボトルを充填雪片のように、特に最終的には、コードを非常に肥大化した感じになります。

オンラインあなたを幸せにするために、嘲笑のPythonの神図は、Javaプログラマをプログラマ(侵入は削除)を直接コピーを参照してください。

また、のtry-catch-最後に重大な危険がある最初から最後まで:試みるbr.readLine()可能性がスローIOException、最終的にそれはあるbr.close()も可能性がスローされるようにIOException2は残念ながらIOExceptionがスローされた場合、プログラムは再び複雑になるというタスクをデバッグし、最後のミスでに、あなたは多くの労力を費やす必要があり、これは我々が見たいと思った結果です。

上記をシミュレートするために、我々は、それぞれ、2つのメソッドがありMyfinallyReadLineThrow、からクラスを定義し、readLine()そしてclose()、アクティブスローメソッド本体です。

class MyfinallyReadLineThrow {
    public void close() throws Exception {
        throw new Exception("close");
    }

    public void readLine() throws Exception {
        throw new Exception("readLine");
    }
}
复制代码

私たちは、その後main()のtry-ついにMyfinallyReadLineThrowメソッドを呼び出す方法を使用readLine()してclose():メソッドを

public class TryfinallyCustomReadLineThrow {
    public static void main(String[] args) throws Exception {
        MyfinallyReadLineThrow myThrow = null;
        try {
            myThrow = new MyfinallyReadLineThrow();
            myThrow.readLine();
        } finally {
            myThrow.close();
        }
    }
}
复制代码

上記のコードを実行した後、エラー・スタックを次のように

Exception in thread "main" java.lang.Exception: close
	at com.cmower.dzone.trycatchfinally.MyfinallyOutThrow.close(TryfinallyCustomOutThrow.java:17)
	at com.cmower.dzone.trycatchfinally.TryfinallyCustomOutThrow.main(TryfinallyCustomOutThrow.java:10)
复制代码

readLine()例外情報方法についてされているclose()私たちは誤っ目標は調べることであると思わせるためにバインドされているスタック情報法、食べclose()代わりの方法をreadLine()、それもあるが、オブジェクトは懐疑的でなければなりませんが- 。

しかし、試し-と資源の導入により、これらの問題は、実装AutoCloseableインターフェース限り(例えばBufferedReaderのような)リソースを解放する必要があるとして、解決されるだろう。以下のソリューションにより、我々は最終的に、コードブロックの薄い前に右に来ます。

try (BufferedReader br = new BufferedReader(new FileReader(decodePath));) {
    String str = null;
    while ((str =br.readLine()) != null) {
        System.out.println(str);
    }
} catch (IOException e) {
    e.printStackTrace();
}
复制代码

あなたが見る、finallyブロックがなくなって、書き込みしようとした後にリリースされるリソースに置き換え()インチ リリースされる複数のリソース(BufferedReaderのとのPrintWriter)がある場合は、直接することができます()で追加します。

try (BufferedReader br = new BufferedReader(new FileReader(decodePath));
     PrintWriter writer = new PrintWriter(new File(writePath))) {
    String str = null;
    while ((str =br.readLine()) != null) {
        writer.print(str);
    }
} catch (IOException e) {
    e.printStackTrace();
}
复制代码

あなたは、それがAutoCloseableインタフェースを実現し、提供して、カスタムリソースを解放したい場合はclose()、あなたができる方法を。

public class TrywithresourcesCustom {
    public static void main(String[] args) {
        try (MyResource resource = new MyResource();) {
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class MyResource implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("关闭自定义资源");
    }
}
复制代码

次のようにコードを実行した後に結果を出力します。

关闭自定义资源
复制代码

それは驚くほどではないですか?私たちは、try ()他には何もしなかった、ちょうど新しいmyresourceでのオブジェクトです、まだclose()出力文メソッドが実行されます。理由を知りたいですか?それを逆コンパイルするバイトコードを見てみましょう。

class MyResource implements AutoCloseable {
    MyResource() {
    }

    public void close() throws Exception {
        System.out.println("关闭自定义资源");
    }
}

public class TrywithresourcesCustom {
    public TrywithresourcesCustom() {
    }

    public static void main(String[] args) {
        try {
            MyResource resource = new MyResource();
            resource.close();
        } catch (Exception var2) {
            var2.printStackTrace();
        }

    }
}
复制代码

ねえ、コンパイラは、形質転換したかかったのtry-と資源に呼び出してみてくださいclose()方法。

次に、我々は、カスタムクラスに追加するout()方法、

class MyResourceOut implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("关闭自定义资源");
    }

    public void out() throws Exception{
        System.out.println("沉默王二,一枚有趣的程序员");
    }
}
复制代码

今回、我々はトライで呼んでout()方法:

public class TrywithresourcesCustomOut {
    public static void main(String[] args) {
        try (MyResourceOut resource = new MyResourceOut();) {
            resource.out();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
复制代码

そして、逆コンパイル、バイトコードを見てみましょう。

public class TrywithresourcesCustomOut {
    public TrywithresourcesCustomOut() {
    }

    public static void main(String[] args) {
        try {
            MyResourceOut resource = new MyResourceOut();

            try {
                resource.out();
            } catch (Throwable var5) {
                try {
                    resource.close();
                } catch (Throwable var4) {
                    var5.addSuppressed(var4);
                }

                throw var5;
            }

            resource.close();
        } catch (Exception var6) {
            var6.printStackTrace();
        }

    }
}
复制代码

この時間は、catchコールへのイニシアチブをブロックしresource.close()、そして非常に重要なコードがありますvar5.addSuppressed(var4)それは何を使用ですか?例外がスローされると、そこに例外が抑制されるため、他の珍しいすることができ、ひいては適切に投げることができません。することで、この場合、addSuppressed()これらのメソッドを抑制する方法が記録されています。抑制例外は、あなたにもできるでスロー異常なスタック情報で発生するgetSuppressed()これらの異常を取得する方法。これの利点は、デバッグに私たちの開発を促進するために、任意の例外を失っていません。

うわー、私たちの前の例と考えていない-のtry-最終的にreadLine()例外情報方法は、現在中であるclose()食べるのスタック情報方法。さて、試し-リソースと、役割と見てreadLine()一貫性のあるアプローチのout()方法されることはありませんclose()食べ。

close()およびout()メソッドの直接例外をスロー:

class MyResourceOutThrow implements AutoCloseable {
    @Override
    public void close() throws Exception {
        throw  new Exception("close()");
    }

    public void out() throws Exception{
        throw new Exception("out()");
    }
}
复制代码

これら2つのメソッドを呼び出します。

public class TrywithresourcesCustomOutThrow {
    public static void main(String[] args) {
        try (MyResourceOutThrow resource = new MyResourceOutThrow();) {
            resource.out();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
复制代码

次のようにプログラムの出力結果は、次のとおりです。

java.lang.Exception: out()
	at com.cmower.dzone.trycatchfinally.MyResourceOutThrow.out(TrywithresourcesCustomOutThrow.java:20)
	at com.cmower.dzone.trycatchfinally.TrywithresourcesCustomOutThrow.main(TrywithresourcesCustomOutThrow.java:6)
	Suppressed: java.lang.Exception: close()
		at com.cmower.dzone.trycatchfinally.MyResourceOutThrow.close(TrywithresourcesCustomOutThrow.java:16)
		at com.cmower.dzone.trycatchfinally.TrywithresourcesCustomOutThrow.main(TrywithresourcesCustomOutThrow.java:5)
复制代码

まあ、それはこの頃、out()例外スタック情報をプリントアウトして、close()上のキーワードを追加するスタック情報方法Suppressed一見、良い良いが、私はそれが好き。

閉じなければならないリソースを扱うとき要約すると、いつものtry-と資源、かなりのtry-catch-ついにより限定された使用を検討してください。前者は、コードより簡潔、よりトリッキー生成明らかと例外情報を生成します。OK、私を約束?try-catch-最終的には使用しないでください。

謝辞

さて、この記事の内容全体だ私の親愛なる読者は、私が感じて、新しい知識を学ぶことではないのですか?私は黙っ王、1人の面白いプログラマでした。オリジナルは、容易ではない、彼らは白の投票はならない、あなたはこの記事のためにそれのポイントを賞賛、それは私が、より質の高い記事最強のパワーを書くことになります。

あなたがあなたの記事少しの助けと考えられる場合は、マイクロチャンネルサーチ「  王、沈黙  読んで初めて、[への対応」666私は慎重にあなたのための準備]より500G HD教育ビデオを(すでに分類)。この記事  のGitHubは  すでに含まれ、完全なインタビューの巨大なテストセンターがあり、スターを歓迎しました。

おすすめ

転載: juejin.im/post/5e87cb9be51d4546cf777342