How to avoid 'unchecked cast'?


#1

Can you guys help me to fix the following code in Kotlin? Any suggestion is really welcome.

Thanks in advance.

// EVENT -----------------------------------------------
interface Event {
}
class NewTicketEvent(val title: String) : Event
class NewCommentEvent(val comment: String) : Event
// -----------------------------------------------------

// FORMATTER FOR EVENTS --------------------------------
interface Formatter<T: Event> {
  val eventType: Class<out T>
  fun format(event: T): String
}
class FormatterForNewTicketEvent : Formatter<NewTicketEvent> {
  override val eventType: Class<out NewTicketEvent>
  get() = NewTicketEvent::class.java

  override fun format(event: NewTicketEvent): String {
  return “New Ticket Event: ${event.title}”
  }
}
class FormatterForNewCommentEvent : Formatter<NewCommentEvent> {
  override val eventType: Class<out NewCommentEvent>
  get() = NewCommentEvent::class.java

  override fun format(event: NewCommentEvent): String {
  return “Ticket Commented Event: ${event.comment}”
  }
}
// -----------------------------------------------------

// REGISTRY FOR FORMATTERS -----------------------------
class FormatterRegistry(
  initialFormatters: List<Formatter<out Event>> = listOf(
           FormatterForNewTicketEvent(),
           FormatterForNewCommentEvent()
  )
) {
  var formatters = initialFormatters.toMapBy { it.eventType }

  fun <T: Event> getByClass(eventType: Class<out T>): Formatter<T> {
  return formatters[eventType] as Formatter<T>? // <-------- How to avoid this casting?
           ?: throw IllegalArgumentException(“Invalid event type: ‘$eventType’”);
  }
}
// -----------------------------------------------------

// SOME TESTS ------------------------------------------
fun main(args: Array<String>) {
  val formatterRegistry = FormatterRegistry()

  var formatter: Formatter<Event> = formatterRegistry.getByClass(NewTicketEvent::class.java)
  println(formatter.format(NewTicketEvent(“a new ticket!”)))

  formatter = formatterRegistry.getByClass(NewCommentEvent::class.java)
  println(formatter.format(NewCommentEvent(“a new comment!”)))
}
// -----------------------------------------------------