質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

8733閲覧

try-with-resources文を使用しているのに「リソースが閉じられない」という警告が出る

swordone

総合スコア20649

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2015/10/09 10:09

編集2015/10/09 13:53

Eclipse4.4.2でJava8を使用しています.

java

1public class Main { 2 3 public static void main(String[] args) { 4 try (Reader reader = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(reader)){ 5 String[] input = br.readLine().split(","); 6 int start = Integer.parseInt(input[0]); 7 int end = Integer.parseInt(input[1]); 8 int count = (int)IntStream.range(start + 1, end) 9 .parallel() 10 .filter(e ->{//(ある出題サイトの回答の根幹なので伏せます) 11 }).peek(e -> System.out.println(e + " " + Integer.toBinaryString(e))).count(); 12 System.out.println(count); 13 } catch (IOException e) { 14 e.printStackTrace(); 15 } 16 } 17 18}

このようなコードで,tryの後の括弧にあるreaderとbrに黄線が出現し,「リソースリーク:’reader(またはbr)’が閉じられることはありません」と表示されます.
tryブロックがint end = Integer.parseInt(input[1]);の行までの場合はその部分に黄線は出現せず,使われていないstart,endに警告が出るだけなのですが・・・
なぜtry-with-resources文を使用しているにもかかわらずこのようなことが起こるのでしょうか?

伏せてる部分を(e -> true)にしたら警告は消えました.
伏せてる部分でやってるのはビットシフトとビット積と比較演算で,
使っているメソッドはInteger.highestOneBitだけです.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

argius

2015/10/09 13:19

Eclipse4.4.2+Java8で、プロジェクトのコンパイラー設定はresource leakの2つのチェックを警告にして、貼っていただいたコードのfilterはラムダ式を(e ->{ return true; })にしてコンパイルしてみましたが、警告は出ませんでした。 swordoneさんの環境では伏せている部分を改変して再現が可能でしょうか?
guest

回答1

0

ベストアンサー

明確な情報が得られなかったのですが、情報連携します。

filterのラムダ式を下記のようにすると、問題が再現しました。
※Eclipse Mars v4.5.0でも再現しますが、v4.5.1(現時点での最新版)では下記のコードは警告が出なくなっています。

lang

1e -> { 2 for (int i = 0; i < 1; i++) { 3 if (e == 0) { 4 return false; 5 } 6 } 7 return true; 8}

EclipseのJava8対応は、新しいバージョンではだいぶマシにはなってきましたが、対応直後はラムダ絡みのバグがけっこうたくさんありました。
特に、カッコが入れ子になったりすると、うまく行かない場合が多かった記憶があります。

今回のケースも、もしかしたらバグなのかも知れません。

ちなみに、ラムダ式を変数にしてループの外に置くと、警告が出なくなりました。

lang

1IntPredicate filterPredicate = e -> { 2 for (int i = 0; i < 1; i++) { 3 if (e == 0) { 4 return false; 5 } 6 } 7 return true; 8}; 9try (Reader reader = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(reader)) { 10 String[] input = br.readLine().split(","); 11 int start = Integer.parseInt(input[0]); 12 int end = Integer.parseInt(input[1]); 13 int count = (int)IntStream.range(start + 1, end).parallel().filter(filterPredicate) 14 .peek(e -> System.out.println(e + " " + Integer.toBinaryString(e))).count(); 15 System.out.println(count); 16} catch (IOException e) { 17 e.printStackTrace(); 18}

投稿2015/10/09 14:30

編集2015/10/09 15:30
argius

総合スコア9388

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2015/10/09 14:38

なるほど,バグの可能性があるのですね. 色々な検証をしていただき,ありがとうございました.
swordone

2015/10/09 14:46

伏せているラムダ式を変数に抽出しても警告が消えなかったので匿名クラスにした所,警告が消えました.
argius

2015/10/09 14:52

警告が消えるかどうかは別として、ラムダ式をメソッドにしてメソッド参照を使うという手もありますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問