Как Firestore `documentSnapshot.toObject (className :: class.java)` переназначает значения `val`, которые были установлены в первичном конструкторе? - PullRequest
0 голосов
/ 12 мая 2019

Я разрабатывал серверную службу Kotlin и наткнулся на метод Firestore documentSnapshot.toObject(className::class.java).

Возьмите следующий Kotlin data class:

data class Record(
        val firstName: String = "",
        val lastName: String = "",
        val city: String = "",
        val country: String = "",
        val email: String = "")

Иследующий код из моего Repository класса:

if (documentSnapshot.exists()) {
    return documentSnapshot.toObject(Record::class.java)!!
}

Теперь, насколько я понимаю, метод documentSnapshot.toObject(className::class.java) требует и вызывает конструктор по умолчанию без параметров, например val record = Record().

Этот вызов вызовет основной конструктор и назначит значения по умолчанию, указанные в нем (в случае класса данных Record, пустые строки ""), для полей.

Затем он использует методы открытого установщика для установки полей экземпляра со значениями, найденными в document.

Как это возможно, учитывая, что поля были помечены как val в конструкторе первичного класса данных?Здесь играет роль отражение?Разве val не действительно окончательно в Котлине?

1 Ответ

0 голосов
/ 12 мая 2019

Firebase действительно использует отражение для установки / получения значений.В частности, он использует шаблон JavaBean для идентификации свойств, а затем получает / устанавливает их либо используя их public getter / setter, либо используя public поля.

Ваш data class скомпилирован в эквивалент этогоКод Java:

public static final class Record {
  @NotNull
  private final String firstName;
  @NotNull
  private final String lastName;
  @NotNull
  private final String city;
  @NotNull
  private final String country;
  @NotNull
  private final String email;

  @NotNull
  public final String getFirstName() { return this.firstName; }
  @NotNull
  public final String getLastName() { return this.lastName; }
  @NotNull
  public final String getCity() { return this.city; }
  @NotNull
  public final String getCountry() { return this.country; }
  @NotNull
  public final String getEmail() { return this.email; }

  public Record(@NotNull String firstName, @NotNull String lastName, @NotNull String city, @NotNull String country, @NotNull String email) {
     Intrinsics.checkParameterIsNotNull(firstName, "firstName");
     Intrinsics.checkParameterIsNotNull(lastName, "lastName");
     Intrinsics.checkParameterIsNotNull(city, "city");
     Intrinsics.checkParameterIsNotNull(country, "country");
     Intrinsics.checkParameterIsNotNull(email, "email");
     super();
     this.firstName = firstName;
     this.lastName = lastName;
     this.city = city;
     this.country = country;
     this.email = email;
  }

  ...

}

В этом случае Firebase использует публичные методы получения, чтобы получить значения свойств, когда мне нужно записать их в базу данных, и поля, когда это необходимоустановить значения свойств при чтении их из базы данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...