ZonedDateTime覚書

私はアプリ内で時刻を取り扱う際には、基本的にZonedDateTimeを使うようにしている。しているのだが、基本のセットアップをした後はあまり複雑なことをしない。そのため別プロジェクトで新たにセットアップをする際、いつも「あれ、どうやるんだっけ」となってしまう。

一応個人的メモは持っているものの非効率なので、よく使う設定を覚書としてメモしておこうと思う。ちなみにAndroidで使う場合の話をメインにするが、JavaでZonedDateTimeを扱うときと基本は同じだと思う。

正直なところ理解があやふやな部分もあるので、間違いがあったら指摘してほしい。

Read full post gblog_arrow_right

ラムダ式とは一体何なのか

Java8から使えるようになったラムダ式はAndroidではそのままでは使えません。Android Studioが「ラムダ式で書いたらこうなる」と見た目だけ表示してくれたりしますが、実際にラムダ式でコードが記述されているわけではありません。

例えば、このようなボタンにクリックリスナーを設定するコードがあったとして、

mButton.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v){
        Log.d(TAG, "Click!!");
    }
});

Android Studioがラムダ式スタイルで見た目をすっきりさせてくれるわけです。

mButton.setOnClickListener((v) -> { Log.d(TAG, "Click!!"); });

これはエディタ上で折りたたまれて表示されているだけで、実際に記述されているコードは上のものです(マウスカーソルを上に持って行くと表示されます)。

で、これを本当にラムダ式で記述できるようにするライブラリとしてretrolambdaというものがあります。あるんですが、その前に、そもそも私はラムダ式自体がよく分かっていません。そこでまずは、ラムダ式とはなんぞやというところから調べることにしました。

ざっくりした書き方で、私の中のイメージを書き連ねたのでわかりにくいところがあると思います。間違ってるところもあると思いますが、その際はご指摘いただけるとうれしいです。(長い前置き終わり)

ラムダ式はいろいろ省略することのできる記法

ラムダ式はアロー演算子を利用して(引数) -> {処理}という書き方ができるものです。この書き方ができるのは一定の条件下においてですが、引数にOnClickListenerのような抽象メソッドが1つだけのinterfaceを取る場合と考えておけばいいと思います。

OnClickListenerは以下のように、onClickという抽象メソッドが1つだけ定義されたインターフェースです。

    public interface OnClickListener {
        /**
         * Called when a view has been clicked.
         *
         * @param v The view that was clicked.
         */
        void onClick(View v);
    }

これをsetOnClickListener()する際に、無名クラスとして定義して使っているわけですが、その無名クラスの定義をすっ飛ばして、直接抽象メソッドへの引数と処理だけを書くことができるのです。

なぜ省略できるか

なぜ省略して書けるかというと、まずsetOnClickListener()というメソッドは、引数にOnClickListenerというインターフェースをとります。そしてJavaのinterfaceという仕組みによって、onClick()というメソッドが必ず実装されていることが保障されます。すなわち、この中では少なくともonClick()というメソッドが呼ばれることがわかっているわけです。だから省略できるのです。

ラムダ式の左辺については、引数が1つであれば()を省略できたり、型を省略することができます。型を省略できる理由は、インターフェースの定義で型が決められているため、省略されても分かるからです。

右辺の{}はメソッドの中身が1文ですむ場合に省略可能です。また、return文だけですむ場合も同様で、さらにreturn句も省略できます。なぜならソッドの戻り値がインターフェースの定義で決められており、右辺の処理が戻り値を表していると自明だからです。

あくまでこれらは「省略できる」であって、別に省略せずに書いても問題ありません。(もっともわざわざラムダ式を使う目的を考えれば、省略できるところは省略すべきでしょうが)

それでも分からない人に、もしかしたら引っかかるかもしれない情報

省略して書けることは分かったけど、やっぱりラムダ式よく分からない。そんな人は、「そもそもなぜメソッド1つだけが定義されたinterfaceを用意して使っているのか」が分かっていないことが原因かもしれません(私はそうでした)。

ラムダ式が適用できるパターンが全てそうかは知りませんが、少なくともOnClickListenerについてはObserverパターンによる実装です。なぜメソッド1つだけのinterfaceを定義して使うかというと、「クリックされた」というイベントを監視するのに便利だからです。

Read full post gblog_arrow_right