Staram się, aby Room ( https://developer.android.com/topic/libraries/architecture/room ) pracował z wbudowanymi klasami Kotlina, jak opisano w artykule Jake Whartonsa Klasy Inline Twórz świetne identyfikatory baz danych :
@Entity
data class MyEntity(
@PrimaryKey val id: ID,
val title: String
)
inline class ID(val value: String)
Na kompilację tego pokoju narzeka
Podmioty i Pojos muszą mieć użytecznego konstruktora publicznego. Możesz mieć pustego konstruktora lub konstruktora, którego parametry odpowiadają polom (według nazwy i typu).
Przeglądając wygenerowany kod Java, znajduję:
private MyEntity(String id, String title) {
this.id = id;
this.title = title;
}
// $FF: synthetic method
public MyEntity(String id, String title, DefaultConstructorMarker $constructor_marker) {
this(id, title);
}
W tajemniczy sposób domyślny konstruktor jest teraz prywatny.
W przypadku użycia String
jako typu id
(lub a typealias
) wygenerowany konstruktor klasy Java wygląda tak, jak powinien:
public MyEntity(@NotNull String id, @NotNull String title) {
Intrinsics.checkParameterIsNotNull(id, "id");
Intrinsics.checkParameterIsNotNull(title, "title");
super();
this.id = id;
this.title = title;
}
Czy ktoś może teraz zachować domyślny konstruktor jako publiczny, używając klas wewnętrznych jako właściwości encji danych?
Odpowiedzi:
Uważam, że powodem jest to, że klasa ID będzie reprezentowana jako ciąg w czasie wykonywania. Zatem dodatkowy parametr $ constructor_marker ma zagwarantować unikalność podpisu konstruktora MyEntity (identyfikator ciągu, tytuł ciągu), ponieważ ten konstruktor mógł zostać już zdefiniowany. Ale spekuluję tutaj.
Czy możesz spróbować jawnie zdefiniować tego konstruktora w klasie MyEntity i sprawdzić, czy działa?
źródło
data class MyEntity(@PrimaryKey val id: ID, val title: String)