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

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

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

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

Q&A

解決済

2回答

1928閲覧

java scannerの警告について

ganogano

総合スコア2

Java

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

0グッド

0クリップ

投稿2020/06/15 08:10

前提・実現したいこと

プログラミングを初めて約一ヶ月です。現在Javaでブラックジャックを作成中です。
BlackjackクラスやMainクラスにあるscannerについてなのですが現在「リーク: 'scan' が閉じられることはありません」という警告が出ています。
繰り返し使うので.closeすることはできません。
この警告は私自身で調べた限りでは警告は出てしまうものなので無視する、気になるようであれば@suppressWarning(resourse)で消す
と学んだのですが
できれば他のきちんとした方法で消してほしいと言われている状態で困っております。
他にどのような解決策があるでしょうか。

scannerが使われているクラスだけ載せています。
ご助力宜しくお願い致します。

該当のソースコード

java

1import java.util.ArrayList; 2import java.util.InputMismatchException; 3import java.util.List; 4import java.util.Scanner; 5 6/* カード枚数は52枚。ジョーカーは含めない。カードの重複が無いように山札を構築する。 7プレイヤー、ディーラーの一対一で対戦するものとし、以下の挙動を取る 8初期設定として、プレイヤー・ディーラーが交互に1枚ずつ山札からカードを取り手札とする。 9プレイヤーからは自分の手札すべてと、ディーラーの1枚めの手札が確認できる。(ディーラーの2枚目移行の手札はわからない) 10 11手札はAが1ポイント、2-10がそれぞれ2-10ポイント、J/Q/Kが10ポイントとして計算される。 12 13プレイヤーは手札を1枚追加するか、しないかを選択できる。 14手札を追加した場合、21ポイントを超えるとバーストとなり、ゲームに敗北する。 15プレイヤーはバーストするか、好きなタイミングで止めるまで手札にカードを追加できる。 16ディーラーは手札の合計ポイントが17以上になるまで山札を引き続ける。 17ディーラーの手札が21ポイントを超えた場合、バーストしてプレイヤーの勝利。 18ディーラーの手札が18以上21以下になったとき次の段階に移行する。 19 20プレイヤー・ディーラーの手札のポイントを比較して、大きいほうが勝利。 21 22ダブルダウン・スプリット・サレンダーなどの特殊ルールは無し。 */ 23 24 25public class Blackjack { 26 27 /** ゲームの勝敗を記録する */ 28 private int win = 0; 29 private int lose = 0; 30 private int draw = 0; 31 32 /** 賭けに使う所持チップ数とベット数 */ 33 public int tip = 10; 34 private int bet = 0; 35 36 /** 山札の進行状況を記録する変数を定義 */ 37 private int deckCount = 4; 38 39 /** プレイヤーの手札枚数を記録する変数を定義 */ 40 private int playerHands = 2; 41 private int dealerHands = 2; 42 43 /** プレイヤーとディーラーの手札のポイントを定義 */ 44 private int playerPoint = 0; 45 private int dealerPoint = 0; 46 47 /** プレイヤー・ディーラーの手札リストを生成 */ 48 List<Integer> player = new ArrayList<>(); 49 List<Integer> dealer = new ArrayList<>(); 50 51 /** DeckクラスとCardクラスのインスタンスを作成 */ 52 Deck deck = new Deck(); 53 Card card = new Card(); 54 55 /** 56 * ゲームを繰り返すにあたって初期化する必要がある変数を初期化するメソッド 57 */ 58 public void reset() { 59 60 // 手札リストをリセット 61 this.player.clear(); 62 this.dealer.clear(); 63 64 // 山札の進行状況を記録する変数を再定義 65 this.deckCount = 4; 66 67 // プレイヤーの手札枚数を記録する変数を再定義 68 this.playerHands = 2; 69 this.dealerHands = 2; 70 71 // プレイヤーとディーラーの手札のポイントを再定義 72 this.playerPoint = 0; 73 this.dealerPoint = 0; 74 } 75 76 /** 77 * ゲームを開始するメソッド 78 */ 79 public void start() { 80 81 Scanner scan = new Scanner(System.in); 82 83 // 掛け金を設定する為のwhile文 84 while (true) { 85 try { 86 System.out.println("掛け金を設定して下さい。現在所持チップ" + this.tip + "枚"); 87 this.bet = scan.nextInt(); 88 if (this.bet > 0 && this.bet <= this.tip) { 89 // 入力が正しい場合ブレイク 90 break; 91 } 92 System.out.println("入力を間違えています。1~所持チップ枚数内で入力してください"); 93 } catch (InputMismatchException e) { 94 System.out.println("入力を間違えています。整数で入力してください"); 95 // 入力バッファ初期化の為、読み捨てる 96 scan.next(); 97 } 98 } 99 // デッキクラスのメソッドを呼び出し 100 this.deck.createDeck(); 101 } 102 103 /** 104 * プレイヤーとディーラーが山札からカードを引くメソッド 105 */ 106 public void drawCard() { 107 108 // プレイヤー・ディーラーがカードを2枚引く 109 this.player.add(this.deck.getDeck().get(0)); 110 this.player.add(this.deck.getDeck().get(1)); 111 this.dealer.add(this.deck.getDeck().get(2)); 112 this.dealer.add(this.deck.getDeck().get(3)); 113 } 114 115 /** 116 * 現在ポイントについて記述するメソッド 117 */ 118 public void saidPoint() { 119 // プレイヤー・ディーラーの手札のポイントを表示 120 System.out.println("あなたの1枚目のカードは" + this.card.toDescription(this.player.get(0))); 121 122 System.out.println("ディーラーの1枚目のカードは" + this.card.toDescription(this.dealer.get(0))); 123 124 System.out.println("あなたの2枚目のカードは" + this.card.toDescription(this.player.get(1))); 125 126 System.out.println("ディーラーの2枚目のカードは秘密です"); 127 128 // プレイヤー・ディーラーのポイントを集計 129 this.playerPoint = CardUtil.sumPoint(this.player); 130 this.dealerPoint = CardUtil.sumPoint(this.dealer); 131 System.out.println("あなたの現在のポイントは" + this.playerPoint + "です"); 132 } 133 134 /** 135 * お互いに追加でカードを引くか決め、引いた場合バーストチェックを行うメソッド 136 */ 137 public void battlePhase() { 138 139 /** バーストした場合の結果を表示するための変数を定義 */ 140 boolean yourLose = false; 141 142 // プレイヤーがカードを引くフェーズ 143 while (true) { 144 145 System.out.println("カードを引きますか? Yes:y or No:n"); 146 147 // キーボードの入力を受け付けて、変数strに代入する 148 Scanner scan = new Scanner(System.in); 149 String str = scan.next(); 150 151 if ("n".equals(str)) { 152 // カードを引かない場合、ブレイク 153 break; 154 } else if ("y".equals(str)) { 155 // 手札の追加とバーストチェック 156 157 // 山札から一枚追加 158 this.player.add(this.deck.getDeck().get(this.deckCount)); 159 160 // 山札とプレイヤーの手札を一カウント進める 161 this.deckCount++; 162 this.playerHands++; 163 164 System.out.println("あなたの" + this.playerHands + "枚目のカードは" 165 + this.card.toDescription(this.player.get(this.playerHands - 1))); 166 this.playerPoint = CardUtil.sumPoint(this.player); 167 System.out.println(""); 168 System.out.println("現在のポイントは" + this.playerPoint + "です"); 169 // バースト判定を行う 170 if (CardUtil.isBusted(this.playerPoint)) { 171 // バーストしていた場合true 172 yourLose = true; 173 } 174 } else { 175 System.out.println("入力を間違えています。yかnを入力してください"); 176 } 177 178 // プレイヤーがバーストした場合ディーラー勝利の結果表示 179 if (yourLose) { 180 System.out.println("残念、バーストしてしまいました。あなたの負けです。"); 181 this.lose++; 182 this.tip -= this.bet; 183 System.out.println("--------------------------------------------------"); 184 System.out.println("現在" + this.win + "勝" + this.lose + "負" + this.draw + "分け"); 185 System.out.println("所持チップ枚数 " + this.tip); 186 System.out.println("--------------------------------------------------"); 187 return; 188 } 189 } 190 191 System.out.println("ディーラーの2枚目のカードは" + this.card.toDescription(this.dealer.get(1)) + "でした"); 192 193 // ディーラーが手札を17以上にするまでカードを引くフェーズ 194 while (true) { 195 if (this.dealerPoint >= 17) { 196 // ディーラーの手札が17以上になった場合ブレイク 197 break; 198 } 199 200 // 山札から手札に1枚加える 201 this.dealer.add(this.deck.getDeck().get(this.deckCount)); 202 203 // 山札とディーラーの手札を1カウント進める 204 this.deckCount++; 205 this.dealerHands++; 206 207 // ディーラーのポイント合計を算出 208 this.dealerPoint = CardUtil.sumPoint(this.dealer); 209 210 System.out.println("ディーラーの" + this.dealerHands + "枚目のカードは" 211 + this.card.toDescription(this.dealer.get(this.dealerHands - 1))); 212 213 // ディーラーのバーストしていた場合プレイヤー勝利の結果表示 214 if (CardUtil.isBusted(this.dealerPoint)) { 215 System.out.println(""); 216 System.out.println("ディーラーのポイントは" + this.dealerPoint); 217 System.out.println("ディーラーがバーストしました。あなたの勝ちです。"); 218 this.win++; 219 this.tip += this.bet; 220 System.out.println("--------------------------------------------------"); 221 System.out.println("現在" + this.win + "勝" + this.lose + "負" + this.draw + "分け"); 222 System.out.println("所持チップ枚数 " + this.tip); 223 System.out.println("--------------------------------------------------"); 224 return; 225 } 226 } 227 this.result(); 228 } 229 230 /** 231 * お互いにバーストしなかった場合、ポイントを比較し結果を表示するメソッド 232 */ 233 public void result() { 234 // ポイントを比較する 235 System.out.println(""); 236 System.out.println("あなたのポイントは" + this.playerPoint); 237 System.out.println("ディーラーのポイントは" + this.dealerPoint); 238 // 引き分けの場合 239 if (this.playerPoint == this.dealerPoint) { 240 this.draw++; 241 System.out.println("引き分けです"); 242 // プレイヤー勝利の場合 243 } else if (this.playerPoint > this.dealerPoint) { 244 this.win++; 245 this.tip += this.bet; 246 System.out.println("勝ちました!"); 247 // プレイヤー敗北の場合 248 } else if (this.playerPoint < this.dealerPoint) { 249 this.lose++; 250 this.tip -= this.bet; 251 System.out.println("負けました・・・"); 252 } 253 System.out.println("--------------------------------------------------"); 254 System.out.println("現在" + this.win + "勝" + this.lose + "負" + this.draw + "分け"); 255 System.out.println("所持チップ枚数 " + this.tip); 256 System.out.println("--------------------------------------------------"); 257 258 } 259 260}

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

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

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

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

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

guest

回答2

0

繰り返し使うので.closeすることはできません。

使わなくなった時点(ループを抜けた直後とか、return直前)で、closeすればよいだけでは?

投稿2020/06/15 08:50

momon-ga

総合スコア4820

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

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

ganogano

2020/06/17 00:58

scannerを利用する場面が二回あるのですが一度目をcloseすると二度目の部分でエラーが起きてしまいます。 どうしても一度目のcloseの警告が消せない状態です。
退会済みユーザー

退会済みユーザー

2020/06/17 01:03

newもcloseも一度だけでできるように設計すればいいだけかと
guest

0

ベストアンサー

一度new Scanner(System.in)を作成すると、このScannercloseに伴ってSystem.inまでもcloseされてしまいます。

ということで、new Scanner(System.in)を使う場所で行うこと自体が適当ではないと思われます。Scanner自体をstaticに持たせるなど、別な構造が必要と考えます。

投稿2020/06/17 01:09

maisumakun

総合スコア145183

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

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

ganogano

2020/06/19 00:08

scannerを別クラスに置いたところうまく警告を消すことができました! ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問