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

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

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

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

コーディング規約

コーディング規約とは、コードの書き方についての決め事のことです。 文法のことではなく、そのチームなどの中の約束事としてどのような書き方で行うかを定めるもの。 項目の例として、関数や変数の命名規則、コーディングのスタイル、括弧やインデントの書き方などが挙げられます。

Q&A

解決済

8回答

9671閲覧

例外を投げるだけの関数を作ってよいか。

koikuti

総合スコア50

Java

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

コーディング規約

コーディング規約とは、コードの書き方についての決め事のことです。 文法のことではなく、そのチームなどの中の約束事としてどのような書き方で行うかを定めるもの。 項目の例として、関数や変数の命名規則、コーディングのスタイル、括弧やインデントの書き方などが挙げられます。

3グッド

3クリップ

投稿2017/02/03 05:49

###前提・実現したいこと
javaの決まりというか、慣習というか分かりませんが、引数によって何らかの判定を行い、
判定にマッチした場合例外を投げるだけの関数を作ることはjavaのルールや慣習として許されているでしょうか。

関数の説明

  • 呼び出し元からチェック用の変数を引数として受け取る。
  • 特定の値であれば例外を投げる。
  • 上記の特定の値意外であれば、何もせず呼び出し元に処理が戻る。

###該当のソースコード
例えばこんな感じ

private void errorCheck(String checkTarget){ if(checkTarget.equals("hogehoge")){ throw new SystemException("システムエラー"); } else if(checkTarget.equals("fugafuga")){ throw new BusinessException("業務エラー"); } }

###試したこと
戻り値をvoidでなく、booleanとして例外とならなかった場合は常にtrueを返し、
呼び出し元では戻り値を受け取らず、処理を続行する。

private boolean errorCheck(String checkTarget){ if(checkTarget.equals("hogehoge")){ throw new SystemException("システムエラー"); } else if(checkTarget.equals("fugafuga")){ throw new BusinessException("業務エラー"); } return true; }

###気になる部分
該当のソースコードについて

  • 呼び出し元から見ると、void型の関数を呼んだにもかかわらす処理が終わってしまう事がある。
  • 関数名がcheckとなっているが boolean の戻り値でない。

試してみたことについて

  • 戻り値を boolean と言いつつ、true OR Exception を返すような作りになっている。(正確には例外は返していないが...)
  • 呼び出し元では、戻り値がある関数であるにも関わらず、その戻り値を受取る必要がない。(受け取らない。)

ご回答の程よろしくお願いします。

A-pZ, GrassfieldK, ladybird👍を押しています

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

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

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

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

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

guest

回答8

0

私の個人的な見解では、慣習的な Javaコードとは言えません。

なぜなら、『Effective Java 第2版』(丸善出版)が 第9章 項目57 で
「例外的状態にだけ例外を使用する」
べき、と主張しているからです。

同書は、Javaプログラマのバイブル的な書籍です。
(少なくとも、私はそう思っています(^^;)

ご提示のerrorCheckメソッドは、引数checkTargetが正当な値か否か、そしてどのように不正なのかをチェックするためのメソッドだと見受けます。
であれば、このメソッドに不正な値が渡されることは、「例外的状態」とは言えません。
(それをチェックするためのメソッドなのですから)

大替案として、以下のようにエラーコードを返却する、というのはいかがでしょうか?

java

1private static final int VALID = 0; 2private static final int SYSTEM_ERROR = 1; 3private static final int BUSINESS_ERROR = 2; 4 5private int errorCheck(String checkTarget){ 6 if(checkTarget.equals("hogehoge")){ 7 return SYSTEM_ERROR; 8 } else if(checkTarget.equals("fugafuga")){ 9 return BUSINESS_ERROR; 10 } 11 return VALID; 12}

これなら、例外を投げることなく、修正前のコードと同じ目的を果たすことができます。

ちなみに、なぜ「例外的状態にだけ例外を使用する」べきかは、上述の『Effective Java』を読んで確かめてみてください。
一応、私なりに要約すると、以下のようになります。

  • 可読性が悪い。
  • 例外に基づくイデオムは、標準のイデオムより遅いか、将来的に JVM のバージョンアップによって遅くなる可能性が高い。
  • try/catch句の使用を強制するため、別の場所で発生した例外を隠蔽してしまうかもしれない。

投稿2017/02/03 14:00

編集2017/02/03 14:02
KiyoshiMotoki

総合スコア4791

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

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

0

ベストアンサー

本来はそのcheckTargetを返すメソッドこそが例外を出力すべきだとは思いますが、外部システムと連携している場合など、レスポンスの文字列を判断して処理する流れにせざるを得ない、そして、それを例外に変換し、throwする処理があっても私はよいと思います。checkというメソッド名が気になるなら、validate(検証)はいかがでしょうか。

もしくは、checkTargetを返すメソッドを持ったクラスを更にラップしてしまって、例外判定まで含めた上でcheckTargetの文字列を返すものを作ってみてはどうでしょうか。

投稿2017/02/03 06:04

masaya_ohashi

総合スコア9206

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

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

0

根本的にこういうメソッドが適当かはさておき、作るとしたら「返り値はvoid」で「throwsを書く」という形にすれば、インターフェースレベルで「何も返さないけど例外が飛ぶことがある」というのがはっきりしていいと思います(非検査例外もてthrowsに書けます)。

投稿2017/02/03 05:56

maisumakun

総合スコア145183

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

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

0

「もしエラーなら例外をスローする」ということをするためのメソッドなら、戻り値なしで例外をスローするだけというのは何ら問題ありません。エラーチェック用のメソッドを作ることはごく一般的に行われていますし、私もよくやります(Javaは使いませんがC++とかC#で)。
ただ、メソッド名はそれと判るような名前を付けた方が良いかもしれません。私ならthrowIfErrorとかthrowIfInvalidのような名前にします。

投稿2017/02/03 07:34

catsforepaw

総合スコア5938

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

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

0

private void throwIfError(String checkTarget) throws SystemException, BusinessException{ if(checkTarget.equals("hogehoge")){ throw new SystemException("システムエラー"); } else if(checkTarget.equals("fugafuga")){ throw new BusinessException("業務エラー"); } }

と、しました。

説明不足だった部分があり申し訳ないのですが、外部システムとの連携などの関係で、
どうしても、Exceptionを発生させてエラーメッセージをやり取りする必要があり、
ちょっとおかしな場所(?)でExceptionを投げざるを得なくなり、気になった次第でした。

様々なご意見ありがとうございます。

ベストアンサーには、私の説明に漏れていた、外部システムとの連携等も考慮に入れてくださった、masaya_ohashiさんとさせていただきます。

その他のご意見も、ためになるご意見ばかりでした。
本当にありがとうございました。

投稿2017/02/06 00:44

koikuti

総合スコア50

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

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

0

Webアプリケーションの入力値検証(validation)では、許可できない入力値の場合に例外をスローする実装(ないしはフレームワーク)が多いようですね。

ただし例外ですので、呼び出し元ないしはこの例外を制御している箇所までに、取得しているリソースを開放できているかを気にしないといけません。
それでなければ、矢鱈滅多に例外をスローするのは少々乱暴にも見えます。

投稿2017/02/03 23:16

A-pZ

総合スコア12011

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

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

0

私ならやらない方法ですね。

以下、個人的な意見です。

例外は大域脱出の方法であり、問題がありこのメソッドはこれ以上の処理を進められませんという場合にのみ使うと決めているからです。

大域脱出をするかしないかは、呼び出し側のメソッドが決めるほうがメソッドの独立性が担保できる気がします。

また、チェック処理をまとめると、何がどうして問題になるかわからないので、問題になる処理の直前にチェックを入れる方法を好みます。また、少し複雑なチェックの場合は、個別にチェックメソッド(bool IsDuplicate(string id)など)を定義しておくと正常処理の邪魔になりずらいです。

投稿2017/02/03 08:24

iwamoto_takaaki

総合スコア2883

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

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

0

ObjectsクラスのrequireNonNullメソッドのように、引数がnullでない時は引数そのものを返すようにすればいいのではないでしょうか。

投稿2017/02/03 06:55

swordone

総合スコア20651

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問