Android Javaでフィールドにmプレフィクスをつけるのはやめよう

Android Javaでは昔からAOSPのcoding style guidelineに則ったスタイルがとられることが多いようです。そのなかで、private fieldに "m" (member) や "s" (static member) などのプレフィクスをつけよ、というものがあります。

AOSP Java Code Style for Contributors  |  Android Open Source Project

これはいわゆるハンガリアン記法の変種で、こういうやつですね。

class Recipe {
  private String mTitle;
  private List<String> mSteps;

  // ...
}

これについての態度はプロジェクトごとに様々ですが、たとえばクックパッド社のJavaのスタイルガイドでは明確に否定しています。

styleguide/java.ja.md at master · cookpad/styleguide · GitHub (Android Studio用のスタイル設定ファイル)

[MUST]フィールドにプレフィックスは付けないものとする。

私もこのスタイルガイドを定める議論に参加したのですが、その時は「m/sなどのプレフィクスはそもそも意味がない」「Oracle Javaガイドラインはプレフィクスを否定している」という理由でプレフィクスなしに決まったと記憶しています。

ところで数日前に、Jake Whartonもこのハンガリアン記法を否定するエントリを書いています。"mNo" というタイトルからして、mプレフィクスがいかに滑稽かということを主張したいのかわかりますね。

Just Say mNo to Hungarian Notation - Jake Wharton

エントリは問答形式になっていて、要点は次のとおりです。


Android Javaの公式スタイルガイドがハンガリアン記法をつかえといっているじゃないか

Jake: よく参照される 「Android Java公式スタイルガイド」とやらはAOSPにコントリビュートするときのスタイルガイドだ。Android Javaのコード一般のためのものじゃない。

Androidのサンプルコードはそのスタイルじゃないか

Jake: サンプルコードはAOSPのなかのコードだからAOSPのスタイルに従っているというだけだ。

フィールドに追加された情報はコードレビューのときに役に立つ

Jake: もともとのハンガリアン記法は型情報をつけるものだ(long lUserId など)。*1 フィールドの可視性はコードレビューには役に立たない。さらに悪い事に、名前に付けられた情報が正しいとは限らない。static mContext field のようなものは非常に発見しにくいバグとなる。

フィールドに追加された情報は開発のときに役に立つ

Jake: Android StudioIntelliJ IDEAも見た目でインスタンスフィールドと静的フィールド区別できるようにしている。

Googleが書くスタイルで自分もJavaを書きたいんだ!

Jake: AOSPはたしかにGoogleのプロジェクトの一つだが、GoogleのJavaスタイルガイドハンガリアン記法を否定している。AOSPはGoogleが買収したプロジェクトだということを思い出そう。


私もJakeに賛成で、mプレフィクスを使うべきではないと思っています。

追記1:

最近気づいたのは、m prefix付きだとリフレクションやaptなどのメタプログラミングとどうにも相性が悪いということです。たとえばAndroid Ormaコンパイル時にフィールド名をもとにクエリビルダを生成するのですが、m付きだとそのクエリビルダがたとえば mUserIdEq() などとなってしまいおかしなことになります。クエリビルダのための名前をアノテーションに渡すという方法も考えられますが、そもそもm prefixなしでやればいいだけなので、特に対応はしないつもりでいます。

*1:追記2: これは誤解でした。元のエントリではハンガリアン記法を正しく説明しているのですが、長い上にハンガリアン記法を詳しく解説するのも手間なので省略します。