code: public <T> T get(@NonNull String key, @NonNull TypeToken<T> typeTokenOfT, T defaultValue) {
      Preconditions.checkNotNull(key, KEY_IS_NULL);
      Preconditions.checkNotNull(typeTokenOfT, TYPE_TOKEN_OF_T_IS_NULL);
  
      Type typeOfT = typeTokenOfT.getType();
  
      for (Map.Entry<Class<?>, Accessor<?>> entry : accessorProvider.getAccessors().entrySet()) {
        if (typeOfT.equals(entry.getKey())) {
          @SuppressWarnings("unchecked") Accessor<T> accessor = (Accessor<T>) entry.getValue();
          return accessor.get(key, defaultValue);
        }
      }
  
      if (contains(key)) {
        return jsonConverter.fromJson(preferences.getString(key, null), typeOfT);
      } else {
        return defaultValue;
      }
    }
docs: Gets value from SharedPreferences with a given key and type.
  If value is not found, we can return defaultValue.
  
  @param key key of the preference
  @param typeTokenOfT type token of T (e.g. {@code new TypeToken<List<String>> {})
  @param defaultValue default value of the preference (e.g. "" or "undefined")
  @param <T> return type of the preference (e.g. String)
  @return value from SharedPreferences associated with given key or default value