2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SharedPreferencesの@Nullableは実質的に@NonNullという話

Posted at

SharedPreferences の @Nullable問題

問題の発端は SharedPreferences の getString の処理はこのように定義されていることにある。

SharedPreferences.java
@Nullable
String getString(String key, @Nullable String defValue);

戻り値に @Nullable のアノテーションが指定されているため、getString で取得した値をnullチェックせずに使用するとチェックツールに怒られる。
ところが、時には設計上絶対に null にはならない処理もある。nullチェックを書けばそれはデッドコードになるだろう。しかし書かなければチェックツールに怒られる。

書けば デッドコード、書かなければ 規約違反、さてどうしよう。

というわけで実験

全部で4x3パターンしかないので、どんなときに null が返却されるのか見てみよう。

実験.java
SharedPreferences pref = getSharedPreferences("🤔", Context.MODE_PRIVATE);

String key0 = "key0";
String key1 = "key1";
String key2 = "key2";
String key3 = "key3";

// key0はputStringしない
pref.edit().putString(key1, null).commit();
pref.edit().putString(key2, "").commit();
pref.edit().putString(key3, "🎁").commit();

String result00 = pref.getString(key0, "");
String result01 = pref.getString(key0, null);
String result02 = pref.getString(key0, "🎁");
.... 省略 ....
String result11 = pref.getString(key3, "🎁");

このプログラムの結果を表にすると以下となる。

↓デフォルト値/設定値→ なし null "" (空文字) 🎁
"" (空文字) "" "" "" 🎁
null null null "" 🎁
🎁 🎁 🎁 "" 🎁
おわかりいただけただろうか....

結論

デフォルト値に null を指定して、ぬるぽの危険性をわざわざ仕込む必要もないので、

第2引数のデフォルト値に null を指定しない限り @NonNull と考えて問題ない

SharedPreferences の get〇〇 メソッドを包むラッパーがいてくれるといいなって。

SharedPreferencesWrapper.java
@NonNull
public String getString(String key, @NonNull String defValue) {
    .... 省略 ....
}

おまけ


Q. そもそも実験するまでもなくソース見れば一目瞭然ですよね?

A. 全くもってその通りで SharedPreferencesImpl の処理を最初に見ればよかったのです

SharedPreferencesImpl.java
@Nullable
public String getString(String key, @Nullable String defValue) {
    synchronized (this) {
        awaitLoadedLocked();
        String v = (String)mMap.get(key);
        return v != null ? v : defValue;
    }
}

Q. SharedPreferencesってinterfaceですよね?

A. はい、そうです。
そのため、自分で実装クラスを書いていて、引数のデフォルト値以外からnullを返すような実装をしている場合はこの限りではありません。
まぁ、自分で SharedPreferences を実装している人なんて圧倒的少数だと思いますが....

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?