2016/06/13

[android]Handlerの変数でLintの警告が出る

Hnadlerの変数で、Lintの警告が出ている。

 

これだと何も言われない。
private Handler mHandler = new Handler();

なのに、こうすると、なにやら警告が出てくる。
TwoSpinnersで、BLE用に作ったサービスからのコールバックを受け取るここですな。
private Handler mHandler = new Handler() {};

 

このHandlerクラスをstaticにしないとメモリリークするかもしれんぞ、というような内容だ。
じゃあ、static変数にすればいいや、とstaticを頭に付けたのだが、変わらない。

そういう話ではないということ?
ここに至って、ようやくJavaについて調べることにした。

 

classの中に書くclassには、いくつか種類がある。
この呼び名だが、なんかいろいろある。。。
今のところオラクルのドキュメントが正になる気がするので、そこから見ていこう。


まず、大きなくくりとしてNested Classesと呼ぶようだ。
staticがついたものをStatic Nested Classes、staticがついていないものをInner Classesとしてある。
ちなみに、Nested Classesの外側になるのは、Outer Classesだと思うが、文章ではenclosing classとも書いているから、そっちかもしれん。

「Nested classesは2つのカテゴリに分けられる」とあるから、この2つがそのカテゴリになる。
こう書きつつも「Non-static nested classes(inner classes)」と括弧で書いているから、何だかわかりづらい。
用語を作ったのなら、もう力で押し切ってほしいのだが。。。

 

Static Nested Classesは1種類だけだが、Inner Classesの方は別パターンが2種類ある。
1つがLocal Classes、もう1つがAnonymous Classes

そして、Static Nested Classes、Inner Classesと同列に「Shadowing」「Serialization」という項目がある。

「Shadowing」は、引数と、Nested Classesのフィールドと、Enclosing Classのフィールドに同じ名前のものがあった場合のサンプルソースが載っている。
そういう場合、Nested Classの中からはEnclosing Classのフィールドは触れませんよ、というのが、隠されている(shadow)という意味なのかな。

「Serialization」は、Inner Classesをシリアライゼーションするときは注意せんといかんですよ、ということを言っているようだ。
今回のHandlerの話を検索すると、コンパイラが自動的にメソッドを作るなどという言葉が出てきていたので、これが関係しているのかもしれん。
the moon at dawn: handleleakがうざったい。

 

というわけで、こうだ。

  • Nested Classes
    • Static Nested Classes
    • Inner Classes
    • Local Classes(Inner Classesの別バージョン)
    • Anonymous Classes(Inner Classesの別バージョン)

別バージョンというか、special kinds of inner classesとあるから、派生したパターンとかかもしれん。


うーん。

staticが付いている方は、そこそこ独立性が強いから"Nested"として、staticが付いていない方はEnclosing Classに取り込まれているところが強いから"Inner"としたのかしら。

そして、これに日本語の説明が加わると、どの用語がどれなのかわからんごとなってくる。

ここら辺が、どういう名前で呼ばれているのかの参考になりそう。
匿名クラスとかローカルクラスとか - 日々常々

 

中身を省略したLocal ClassesとAnonymous Classsesだが、上記リンクに説明があるのでそちらを読んだ方がよいだろう。
でも、せっかくなのでオラクルの方を眺めておく。

  • Local Classes
    • ブロックに書いたclass
    • メソッドの中に書くのが普通かね
    • (個人の感想)みんな「使わない」って書いてるから、使わないんだろう
  • Anonymous Classses
    • classの宣言と具体化を同時にできる
    • Local Classesと似ているけど、彼らには名前がない
    • (個人の感想)Anonymous ClasssesのためにLocal Classesという仕様が必要だった、ということか

というところまで見ていって、ようやく最初に戻る。

なんでHandlerの変数にstaticを付けてもダメかというと、あれはAnonymous Classsesだから、カテゴリとしてInner Classesになるからだ。
Lintが言いたいのは「Static Nested Classesにしようよ」だから、やり方を変えないといけないのだな。

 

まあ、しょせんLintの警告だから、問題がなければスルーしてよいのだ。
だけど、安全に書く方法があって、特にそれで問題がないなら、変更しようかね。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。