Androidアプリ開発と定数について
- グローバルな定数を作りたい
- どこからでも定数参照したい
- なるべく簡単な方法がいい
こういう時はベストな方法があって、
それがアプリ専用の定数クラスを作ること
定数の定義方法に悩んでいる人のために、
Java/Kotlinでの定数クラスの作り方まとめます。
Javaで定数クラス Constants の定義例
ここではConstantsというクラス名にします。
そのクラスでまとめて定数定義すると楽です。
▼ 定数クラス(Constants.java)のコード例
1 2 3 4 5 |
public class Constants { public static final String VAR_HOGE = "hoge"; public static final String VAR_FUGA = "fuga"; public static final String VAR_PIYO = "piyo"; } |
Constantsクラスを作り、そこに定数定義するだけ。
▼ MainActivity内で定数参照するコード例
1 2 3 4 5 6 7 8 9 10 |
public class MainActivity extends AppCompatActivity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /// 定数参照 String varHoge = Constants.VAR_HOGE; } } |
▼ 名前空間を省略して定数参照
1 2 3 4 5 6 7 8 9 10 11 12 |
/// 定数パッケージインポート import com.myapp.example.Constants; public class MainActivity extends AppCompatActivity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String varHoge = VAR_HOGE } } |
ちなみに定数は文字列・数値などのプリミティブ型にとどめるのがベターです。飽くまで定数なので、ゴチャゴチャ書くべきではないと考えてます。
基本的な定数クラスはこういう感じ
定数クラスを細分化すると見通しがよくなる
それで上記の定数クラスをもっと汎用的にしてみます。
用途に応じてさらに細分化するってことです。
例えば次の2つの目的があるとしましょう
- 色コードを定数定義したい
- サイトURLを定数定義したい
そういう場合、細分化すると見通し良くなります。
▼ 例えば細分化したConstantsクラスの例
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Constants { public static class Colors{ public static final int RED = 0xffff0000; public static final int GREEN = 0xff00ff00; public static final int BLUE = 0xff0000ff; } public static class Urls{ public static final String HOMEPAGE = "https://developer.com"; public static final String PRIVACY_POLICY = HOMEPAGE+"/myapp-privacy-policy"; } } |
▼ MainActivity内で定数参照する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/// 定数パッケージインポート import com.myapp.example.Constants; public class MainActivity extends AppCompatActivity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /// 赤の色コード定数 final int colorRed = Colors.RED; /// プライバシーポリシーのURL定数 final String urlPrivacyPolocy = Urls.PRIVACY_POLICY; } } |
細分化しておくと「コード上で定数が何を表すのか」が一意に決まるし、全定数を直列に書くよりは分かりやすいです。見通しがよくなる
Kotlinでの定数クラス Constants の定義例
それからAndroid開発ではKotlinが主流ですね。
Kotlinでは次のように定数クラスを定義できます。
▼ 定数クラス(Constants.kt)のコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class Constants { class Colors { companion object { const val RED = 0xffff0000 const val GREEN = 0xff00ff00 const val BLUE = 0xff0000ff } } class Urls { companion object { const val HOMEPAGE = "https://developer.com" const val PRIVACY_POLICY = "${HOMEPAGE}/myapp-privacy-policy" } } } |
▼ MainActivity内で定数参照してみる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/// 定数パッケージインポート import com.myapp.example.Constants; class MainActivity: AppCompatActivity(){ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) /// レッドの色コード定数 val colorRed = Colors.RED /// プライバシーポリシーのURL定数 val urlPrivacyPolocy = Urls.PRIVACY_POLICY } } |
色々違うように見えるけど同じことです。
Javaとの違いを挙げるなら以下の2点
- 静的メンバの定義が異なる
Javaではstaticキーワードを使っていたがKotlinにはそんなものはない。代わりに companion object {...} 内で定義したものが静的メンバになる
- 定数宣言がよりシンプルに
Javaだと public static final int HOGEHOGE = ... とか長ったらしいけど、Kotlinだと const val HOGEHOGE = ... だけで済むようになった。
ここは慣れれば問題ありません。
定数インターフェースはアンチパターン
ここからは少しだけ蛇足です。
定数インターフェースはアンチパターンという話
これはググると出てくるけどダメな奴です。
▼ 例えば定数インターフェースのコード例
1 2 3 |
public interface BadConstants { int VAR_HOGE = 1234; } |
そして定数使用するクラスに実装する……
どう考えてもダメそうなパターンです。
何がダメなのかは以下記事で言語化されてました。
▼ 3.7. インターフェースで定数定義
このインターフェースを実装することでクラスでは定数として利用しますが、 その際に、いくつか弊害があります。
まず、「無意味に外部公開してしまう」ということです。 フィールドは「public static final」です。 他のクラスからはこのクラスに属する定数のように見えてしまいます。
また、外部公開しているということは、互換性を保証し続けねばなりません。 つまり、「不要になってもインターフェースを取り除くことができない」ということです。
あと、本来はスーパークラスだけに閉じこめておきたかった定数が、 サブクラスまで出しゃばってきてしまいます。 ということはサブクラスで同名の変数名を定義できません。 つまり、このクラスを継承したサブクラスのすべてにおいて「名前空間が汚染される」といえます。
▼ 上記引用を端的にまとめると…
- 強制的に外部公開になってしまう
- 不要になっても取り除けない
- サブクラスで名前空間が汚染されしまう
メリットがないなので使うべきではないです。
そもそもimplementsが必要な時点で面倒すぎる…
以上、Java・Kotlinで定数定義でした。ではまた