11月1日の学び(その①)

  • ちょっと一日早いけど明日は書けるか不明なので。
  • 単に言葉だけ知ってもしかたなくてベストプラクティスを学ぶのが必要。

例外そもそも論

  • 例外が実装されていない言語(C言語)ではいちいち戻り値をif文で分岐する必要があり面倒。
  • そういう意味ではJavaの例外処理はとても便利。

例外発生後に何をすべきか

  • 最低限例外が障害が発生した事実は把握する必要があるのでログに記載するのは当然。無視し続けると最悪2次障害が発生する。
  • メソッド内で例外が起きた場合一般的には呼ばれる前と同じ状態で戻るのが理想。
  • 握りつぶしはダメ絶対

10月31日の学び②

  • エラーと例外は違う。
  • エラーや例外の実体はインスタンス
  • 「エラーが発生してプログラムが強制終了」「例外が発生してプログラムが強制終了」「例外が発生したがプログラムは強制終了しない」の3通りがあることを意識。

Javaの例外概要(大切)

土台としてエラーと例外の2つあることを意識

  • Error:回復の見込みがないためJVM側で自動終了する。
  • Exception:2種類ある。

エラー

  • java.lang.OutOfMemoryErrorのメモリ不足時など。
  • ログさえ出せないので直ちに停止するべき。
  • すべてcatchして処理するのが常に正しいわけではない

検査例外

  • コンパイラコンパイル時にチェックする例外。例外処理の実装がないとコンパイルに失敗する。
  • FileNotFoundExceptionやSQLExceptionなど。
  • アプリケーション側ではファイルがなかったりした場合はどうしようもない。この例外が発生した場合に責任はアプリケーション側にはない。
  • アプリケーションには責任はないが発生する可能性はあるので処理が必要な場合に用いる。
  • 検査例外を使えば堅牢なアプリケーションとなるが、あちこちに例外処理のthrow/catchが散在する。

実行時例外

  • コンパイラがチェックしない例外。例外処理の実装がなくてもコンパイルに成功する。
  • NullPointerException やIndexOutOfBoundsException。
  • アプリケーションのバグが原因なので、この例外が発生した場合には責任はアプリケーション側。
  • catchを実装してもしなくてもよい。

https://camo.qiitausercontent.com/acf6ba79ca9ccc838f13a49b1a436cc0a91a58db/687474703a2f2f7777772e6a617661726f61642e6a702f696d616765732f657863657074696f6e322e676966

www.milk-island.net

qiita.com

実装例

例外の上位へのスローと自分でのcatchが同居するケースも当然ある。

void doSomething() throws MySpecificException {
    try {
        foo();
    } catch (IOException e) {
        throw new MySpecificException("failed my specific task", e);
    }
}

10月31日の学び

昨日ちょっと書いたことの続き

Javaの例外の概要

  • Javaでは例外が発生しうる処理を呼び出した時try/catch構文を用いて「例外を回復」するか、thorws句にてその例外を上位レイヤーに「通知」するかのどちらか
  • どこで誰が「通知」「回復」するかは設計時に考慮が必要

検査例外

  • もともと例外が発生することを事前に想定しその処理を仕様として扱う
  • 処理を行ったときに発生する可能性のある例外をthrow句にて宣言
  • 呼び出し元でcatchがないとそもそもコンパイルできない
  • 拡張性を考慮して検査例外を使うにはクラス設計の段階から発生しうる例外を種別毎に意識しておくことが必要
class DataStorage {
  DB storage = DB.initialize();

  public Data read(string key) throws DBException {
    return storage.find(key);
  }
}

qiita.com

非検査例外

  • 例外が発生した場合にcatch節やthrows句で対応してはならない/対応する必要はない例外
  • RuntimeExceptionとそのサブクラスが非検査例外
class Example {

    public static void main (String[] args) {
        Example.methodA();
    }

    public static void methodA() {
        throw new RuntimeException("throws unchecked exception");
    }
}

10月30日の学び

UPSERT

  • UPDATE + INSERTのこと
  • データがない場合は新規追加を行い、データがある場合はその既存データを更新する

ロックの種類

  • 行ロック:レコードに対してロック
  • 表ロック:表全体に対してロック

Javaの例外

単に文法をしっているだけでなく、こういうアンチパターンやパターンわからないと業務では何の役に立たない。将棋でいうならばコマの動かし方をしっているだけでは勝てなくて定石を理解しないといけない。

qiita.com

10月29日の学び

スレッド処理の注意点

  • スレッド処理中にsleep処理を実装するのはあまり望ましくない
  • DBアクセス中にsleepに入るとデッドロックの温床になりうる

Visitorパターン

  • 余り使う機会はなさそう
  • thisを使うことで呼び出し元クラスに呼び出し先クラスそのものを受け渡すことができるのは小技として知っておくべし
  • 抽象クラスで予めメソッドをエラーを発生する無意味なメソッドと定義する小技がある。この場合継承先でそのメソッドを使わないならばオーバーライドしないだけで済む

10月28日の学び

↓のサイトは神レベルなので時間があるときに読み込んでおくこと
qiita.com

「仕様の明確でないメソッドを作るのは迷惑行為です!」
「自分にしか理解できないコードを書くことは迷惑行為です!」
「API の仕様を説明できないのであれば、正しいユニットテストを書くことはできません!」

コメントの種類

privateメソッドの場合は後者であり、publicメソッドの場合は前者が相当する - 使い方に関するコメント:APIの利用者向け - 実装に関するコメント:APIの開発者向け

Javadoc

Javadocって自動生成できたのか(オイオイ) - Javaソースコードを元に自動生成されたコメント

Chain of Responsibilityパターン

  • 移譲による継承パターン
  • とくに見るべきものはないが、連鎖を以下のように実装できるのは覚えるべき
alice.setNext(bob).setNext(charlie).setNext(diana).setNext(elmo).setNext(fred);

10月27日の学び

配列とList

  • 配列は宣言時にサイズを決める必要がありサイズは固定のため変更ができない
  • Listはサイズが可変のため必要に応じて変更できる

List

  • ListはCollectionsクラスを継承したインタフェース
public interface List<E> extends Collection<E> {
(略)
}
  • List自体はインタフェースなので利用時はListを実装したクラス経由で生成する
List<E> list = new ArrayList<E>();

Collectionフレームワーク全体図

http://www.itsenka.com/images/development/java/java-collection01.gif