jsc-pの最近のブログ記事


最近、アクセス修飾子やfinalとかをなるべく意識して書こうとしているのですが、
ふと、この変数の値は、~から~でしかありえないよなとか、if文がたくさんあるメソッドでどこかで絶対分岐するはずだから、最後までは絶対に行かないよな、でも最後にreturn文がないとコンパイルが通らない。
こんな、なんともイライラする状況があって、sjc-pの為に覚えたアサーションが使えるんじゃないのかって思って参考書を引っ張り出してきました。

まず、アサーションとは、
プログラムの前提条件を表すもので、プログラムのある部分で必ず真でならなければならないと主張(assert)する条件式を書き、実際にこの条件が満たされる機能を言うらしい。(参考:Wikipedia


じゃぁ、プログラムとして実際にどういう式を書けば良いかというと、
①assert 式;
②assert 式 : 文字列;
という2パターンがある。式には、trueかfalseが返るようなものを、②の文字列には、falseになった時に表示されるエラーメッセージが書ける。
実際に、式がfalseを返すと、AssertionErrorがスローされるが、これはバグを示すためcatchしてはいけない。


・アサーションを有効にする
アサーションを有効にすると、その分評価する式が増えて、パフォーマンスが低下する
なので、実行時に切り替えが出来るようになっている。
javaコマンドで実行するとに、-ea(-enableassertions)オプションをつけると有効に、-da(-disableassertion)をつけると無効になる。
また、このクラスは有効で、このクラスは無効でという風に細かく設定したい場合は、
-ea                    :全てのクラスでアサーションを有効
-ea:<クラス名>    :そのクラスでアサーションが有効
-ea:...                :デフォルトのパッケージとそのサブパッケージに対するアサーションが有効(よくわからんww)
-ea:<パッケージ名>:そのパッケージとそのサブパッケージでアサーションが有効

これの組み合わせにより、
-ea ClassA -da PackageA (パッケージAは無効だけど、クラスAは有効)
-ea -da ClassA                  (クラスA以外は有効)
-da ClassA -ea ClassA      (クラスAが有効)

ここで順番は、後に記述したものが優先されるらしい。ただし、より細かいレベルの指定が優先されるので、上の例だと、後で指定した-da PackageAより、細かいレベルの-ea ClassAが優先される


・アサーションを使うべきところと、使うべきでないところ
アサーションを使うべきところは、プログラム内部の不変条件・制御フローの不変条件、クラスの不変条件である。
プログラムの不変条件とは、冒頭で述べたように





のように、条件的にありえない状態をはじくように使うときで、フロー制御の不変条件は、ほとんど一緒なんだけど
絶対到達しない場所にassert false;を入れる。

クラスの不変条件は、例えば、処理するデータがある条件を満たしているかを確認し、



のように、途中にチェックをデータがおかしくないかチェックを入れるものである。


では、逆に、アサーションを使わないほうがいい場合は、
・publicメソッドの引数チェック
  引数は必ず真であって欲しい条件はあるけど、これはメソッドの仕様であるので、アサーションでチェックするべきではないらしい
・アサーションの式の部分に、その式を評価することによって変数などに変化が起こるものは使用してはいけない。
  これは、アサーションを有効にした場合と無効にした場合で、異なった結果がでてはいけないからである。
  例を出すと、



のように、booleanを返すが、処理が行われるものは、アサーションが無効になった時に実行されないので



のようにしなければならない。

最後に、ユーザの入力に対するチェックはアサーションではなく、
Exceptionや正しく入力するよう促すメッセージを表示するなど、アサーションではないものでやるらしい
これは、アサーションは、プログラムのバグを見つけるための機能であるので、こういうときには使わないらしい

SJC-Pの時に勉強したんだけど、ごっちゃになってきたので、整理しておきます。


あるサブクラスのオブジェクトをスーパークラスの変数として扱ったときに、
フィールドとメソッドで異なった動きをする。

どっちがどっちかわかんなくなったので、実際にプログラムを書いて走らせてみた。



このようなSuperクラスとSubクラスがあったときに、次のプログラムを実行




まとめ
・フィールドは、オブジェクトの型ではなく、変数の型のものが呼ばれる
・メソッドは、変数の型ではなく、オブジェクトの型のものが呼ばれる


iKnow

あわせて読みたいブログパーツ
Firefox meter