Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Esses dias eu estava refatorando um código que usa sealed classes em Java e caí num comportamento que me deixou genuinamente confuso. Imaginem a seguinte hierarquia:
sealed class Shape permits Circle, Quadrangle {} sealed class Quadrangle extends Shape permits Diamond, Rectangle {} final class Rectangle extends Quadrangle {}
final class Diamond extends Quadrangle {}
final class Circle extends Shape {} Até aqui tudo bonito. Agora, quando eu faço um switch assim: switch (shape) { case Rectangle _ -> System.out.println("retângulo"). case Diamond _ -> System.out.println("diamante"). case Circle _ -> System.out.println("círculo"). } Eu cobri todas as subclasses concretas possíveis de Shape. Não existe outra classe que possa estender Shape ou Quadrangle fora dessas. Mas o compilador reclama que o switch não é exaustivo e exige um default. O curioso é que se eu trocar o case Rectangle e case Diamond por case Quadrangle, aí sim o compilador fica satisfeito: switch (shape) { case Quadrangle _ -> System.out.println("quadrilátero"). case Circle _ -> System.out.println("círculo"). } Ou seja, parece que a verificação de exaustividade só olha um nível da hierarquia sealed, não resolve transitivamente. Isso é um bug? É uma limitação proposital da spec? Alguém mais já esbarrou nisso? Estou no Java 21 com preview features habilitadas. Já testei no 22 e o comportamento é o mesmo. Na prática, adicionar um default meio que derrota o propósito de usar sealed classes, porque se amanhã alguém adicionar uma nova subclasse, o compilador não vai avisar que faltou tratar o novo caso. Como vocês lidam com isso? Aceitam o default e colocam um throw new AssertionError() dentro? Ou reestruturaram a hierarquia pra evitar sealed classes intermediárias?Carregando comentários...