Eu tenho esta MappedSuperClass
@MappedSuperclass
abstract class BaseFoo(
...
) : FooItem {
...
}
sealed interface FooItem
Que é então usado assim
@Entity
@Table(name = "bar_1")
class Bar1(
...
) : BaseFoo(
...
) { ... }
@Entity
@Table(name = "bar_2")
class Bar2(
...
) : BaseFoo(
...
) { ... }
@Entity
@Table(name = "all_bar")
class AllBar(
...
@OneToMany(mappedBy = "all_bar", fetch = FetchType.LAZY, cascade = [CascadeType.REMOVE])
val bar1: List<Bar1>? = null,
@OneToMany(mappedBy = "all_bar", fetch = FetchType.LAZY, cascade = [CascadeType.REMOVE])
val bar2: List<Bar2>? = null,
) {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0
val barItems: List<FooItem>
get() = listOfNotNull(bar1, bar2).flatten()
}
Quero então adicionar uma declaração exaustiva quando
val bars = allBarRepository.findById(someId).getOrElse {...}
bars.barItems.forEach {
when (it) {
is Bar1 -> ...
is Bar2 -> ...
}
Mas o compilador diz
A expressão 'when' deve ser exaustiva, adicione o branch 'is BaseFoo' ou o branch 'else' necessários em vez disso
Não quero verificar BaseFoo
, mas apenas Bar1
e Bar2
e se haverá mais Bar_<INT>
para todas as outras Barras que serão adicionadas no futuro. Quero que o compilador reclame quando eu esquecer de adicionar qualquer uma delas Bar_<INT>
aqui. Adicionar uma else
ramificação ou verificar BaseFoo
isso não funcionará mais. Pensei que é para isso que sealed interfaces
pode ser usado?
BaseFoo
também deveria sersealed
.sealed
classes são implicitamenteabstract
, mas classes que são apenasabstract
não sãosealed
. Elas "abrem" a hierarquia, e pode haver outras classes que herdam deBaseFoo
.Um pouco fora do assunto, mas as interfaces/classes seladas do Java exigem que você especifique se cada subclasse é
sealed
/non-sealed
/final
. Eu recomendaria manter isso em mente ao escrever Kotlin também.non-sealed
corresponderia a não ter modificador em Kotlin.