# Unchecked cast while overriding return value by subtype

**URL:** <https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009>\
**Category:** Support\
**Created:** [August 4, 2024, 8:41pm UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009 "2024-08-04T20:41:52Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![DKorchuganov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dkorchuganov/32/5779_2.png) [@DKorchuganov](https://discuss.kotlinlang.org/u/DKorchuganov)\
**Post date:** [August 4, 2024, 8:41pm UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009/1 "2024-08-04T20:41:52Z")

</div>

I have the following generic interface

```auto
interface DataFormatter<T: Any> {
    val kClass: KClass<T>

    fun readFromPath(path: Path): T
    fun writeToPath(path: Path, data: T)
}

```

And an object which implements it

```auto
object TextFormatter : DataFormatter<String> {

  override val kClass: KClass<String> = String::class

  override fun readFromPath(path: Path): String = path.readText()
  override fun writeToPath(path: Path, data: String) = path.writeText(data)
}

```

I also have an interface with generic function which returns `DataFormatter<T>`

```auto
interface FormatterLookup {
  fun <T: Any> formatter(): DataFormatter<T>
}

```

Now I want to create enum with members implementing this interface for particular `DataFormatter<T>`, like this

```auto
enum class DataTypes : FormatterLookup {
  @Suppress("UNCHECKED_CAST")
  TEXT {
    override fun <String: Any> formatter(): DataFormatter<String> = TextFormatter as DataFormatter<String>
  }
}

```

But the compiler reports unchecked cast which I have to suppress. What is the reason and how can I avoid this situation?

---

<div class="post-metadata">

**Author:** ![gidds](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/gidds/32/10865_2.png) [@gidds](https://discuss.kotlinlang.org/u/gidds)\
**Post date:** [August 4, 2024, 9:51pm UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009/2 "2024-08-04T21:51:53Z")

</div>

The first thing that leaps out at me is the `<String : Any>`: it declares a type parameter called ‘String’, as some subtype of ‘Any’. (That’s _not_ related to the normal ‘String’ type.) It then defines the `formatter()` override in terms of that type parameter.

I’m guessing that’s not what you intended…

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [August 4, 2024, 10:01pm UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009/3 "2024-08-04T22:01:41Z")

</div>

Your `formatter` function doesn’t really make sense to me. It is generic and that means the caller provides the `T`. How could implementation of `FormatterLookup` provide exactly the formatter needed by the caller, and especially if the lookup object doesn’t even know what is `T`?

Did you maybe mean to make the `FormatterLookup` generic, instead of its function? This way implementations could be related to specific `T`.

---

<div class="post-metadata">

**Author:** ![DKorchuganov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dkorchuganov/32/5779_2.png) [@DKorchuganov](https://discuss.kotlinlang.org/u/DKorchuganov)\
**Post date:** [August 5, 2024, 5:54am UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009/4 "2024-08-05T05:54:52Z")

</div>

> `<String : Any>` : it declares a type parameter called ‘String’, as some subtype of ‘Any’

Yes, you a right… In fact, it is the same as

`override fun <T: Any> formatter(): DataFormatter<T> = TextFormatter as DataFormatter<T>`

But what is the correct way to override this function with a concrete value of then, namely String class?

---

<div class="post-metadata">

**Author:** ![DKorchuganov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dkorchuganov/32/5779_2.png) [@DKorchuganov](https://discuss.kotlinlang.org/u/DKorchuganov)\
**Post date:** [August 5, 2024, 6:07am UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009/5 "2024-08-05T06:07:04Z")

</div>

> [@broot](#):
>
> Did you maybe mean to make the `FormatterLookup` generic, instead of its function? This way implementations could be related to specific `T`.

I would love to do it, but enum can’t implement generic interfaces because enums can’t be generic, right? Or am I missing something?

In my idea, each enum member should have either property or function which returns its a specific object implementing `DataFormatter<T>` interface of a specific type `T`. So, a enum member knows a specific `T` and can implement formatter() for this specific type.

But it seems this trick doesn’t work. Any other ideas how to overcome the limitation of non-generic enums?

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [August 5, 2024, 8:10am UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009/6 "2024-08-05T08:10:21Z")

</div>

Yes, you are correct, enums are limited. Is there any specific reason why you need enums and you can’t use a singleton object or sealed class?

Also, frankly speaking I’m a little confused with your design. How do you plan to access these formatters in the code? If your case is that at some point we need a formatter specifically for type `String`, so the caller knows the data type, then we can use the `TextFormatter` directly, we don’t need this `DataTypes.TEXT`. If your case is that the caller doesn’t know `T`, e.g. we have a `KClass` and we need a formatter for it, then we can’t use this `DataTypes` anyway. So what benefits do we get from having the `DataTypes`? I don’t say we don’t get any, I’m just curious about use cases.

---

<div class="post-metadata">

**Author:** ![DKorchuganov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dkorchuganov/32/5779_2.png) [@DKorchuganov](https://discuss.kotlinlang.org/u/DKorchuganov)\
**Post date:** [August 5, 2024, 8:14pm UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009/7 "2024-08-05T20:14:12Z")

</div>

> [@broot](#):
>
> I’m just curious about use cases.

Thank you for your interest! Yes, you are right, it makes sense to clarify the overall idea.

I want to read from a YAML/JSON file some metadata about other files in the same folder (let’s name it metadata file). One of the atributes is a String value that is planned to be de-serialized to an enum value, which holds information about particular formatter to read data from this file (or write this file).

Moreover, this is a library, and the enum was supposed to be provided by a user of the library. So, I was planning to de-serialize metadata file to an object of a generic class with a specific user-provided enum implementing the `DataFormatter<T>` interface.

The ultimate goal is to have a library that will allow its users:

1. to define a list of supported data formats along with the corresponding formatters
2. to store information about formats of specific files in a library-defined metadata file
3. to read/write files of specified formats to Kotlin objects in a typesafe way

But it seems I wanted too much or missed something important from Kotlin, or most probably both, lol.

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [August 5, 2024, 8:22pm UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009/8 "2024-08-05T20:22:30Z")

</div>

Hmm, so this is actually my point. If `T` is always dynamic in your case, then you don’t really benefit from having this strongly-typed `DataTypes` class. And it adds boilerplate and complicates the logic. You can have a single, fully dynamic class:

```kotlin

fun main() {
    val reg = FormattersRegistry()
    reg.register(TextFormatter)
    reg.register(DateFormatter)
    
    reg.read(String::class, ...)
}

class FormattersRegistry {
    fun register(formatter: DataFormatter<*>) { ... }
    fun <T : Any> read(type: KClass<T>, path: Path): T { ... }
    fun write(data: Any, path: Path) { ... }
}

```

Of course we can create a function which initializes the registry and adds all formatters. Is there anything you like to do, but can’t with this approach?

---

<div class="post-metadata">

**Author:** ![DKorchuganov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dkorchuganov/32/5779_2.png) [@DKorchuganov](https://discuss.kotlinlang.org/u/DKorchuganov)\
**Post date:** [August 5, 2024, 9:14pm UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009/9 "2024-08-05T21:14:56Z")

</div>

> [@broot](#):
>
> You can have a single, fully dynamic class:

I’m not sure if I completelly understand the suggested (for example, what `register()` function actually does and why `read()` needs `type: KClass<T>` as an argument if we already registered a relevant formatter), but I think I got your general idea.

So, I could have something like

```auto
fun FormatterFactory(type: DataTypes): DataFormatter<*> =
  when(type) {
    DataTypes.TEXT -> TextFormatter
  }

```

The user will provide to the library

- a simple enum that doesn’t implement any interface
- a factory (as a lambda, for example) of type `(DataTypes)-> DataFormatter<*>`

The library will use the provided enum and factory to read data from files, but the user still needs to know the type of data in a file and use it for values which will be serialized/de-serialized to/from this file. I missed the last piece in my initial idea, thank you for pointing it out!

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [August 5, 2024, 10:13pm UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009/10 "2024-08-05T22:13:49Z")

</div>

My main point is: do we even need to require this enum? User of your lib has to first create formatters (e.g. `TextFormatter`, `DateFormatter`), then they additionally need to create enum fields (e.g. `DataTypes.TEXT`, `DataTypes.DATE`), then they probably initialize your lib with something like: `initialize(DataTypes::class)`. And as we can see, we have some problems due to using enums that have some restrictions.

Why not simply: `initialize(TextFormatter, DateFormatter)` and skip the enum part entirely? Or if we need to specify formatter names/ids: `initialize("text" to TextFormatter, "date" to DateFormatter)`.

---

<div class="post-metadata">

**Author:** ![DKorchuganov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/dkorchuganov/32/5779_2.png) [@DKorchuganov](https://discuss.kotlinlang.org/u/DKorchuganov)\
**Post date:** [August 11, 2024, 8:55pm UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009/11 "2024-08-11T20:55:00Z")

</div>

I need enum to serialize data types to the metadata file (maintened by the library, not user). I no longer need to implement any functions in those enums, but they can have some simple properties, like file extension, for example.

`initialize("text" to TextFormatter, "date" to DateFormatter)`

I would prefer using enums instead of strings like `text` and `date` in such maps because enums are more convinient in `when` statements.

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [August 11, 2024, 10:30pm UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009/12 "2024-08-11T22:30:39Z")

</div>

But wouldn’t it be enough if `DataFormatter` had `val id: String` (or `name`)? By having a list of such formatters, we can create a metadata file and we can find a formatter for a specific id/name.

> [@DKorchuganov](#):
>
> I would prefer using enums instead of strings like `text` and `date` in such maps because enums are more convinient in `when` statements.

So I’m back at the question if you ever need such a compile-time formatter resolution? Because all you said feels like the list of formatters is dynamic in your case. Formatters are provided by the user code, library doesn’t know them, so such `when` code is impossible at least in the library code anyway. So to simplify my question: do you ever need to write a code which “knows” very specific formatters and provides different behavior depending on the chosen formatter? Does this happen in the library or in the user code?

---

<div class="post-metadata">

**Author:** ![cabman](https://avatars.discourse-cdn.com/v4/letter/c/50afbb/32.png) [@cabman](https://discuss.kotlinlang.org/u/cabman)\
**Post date:** [October 21, 2024, 2:40am UTC](https://discuss.kotlinlang.org/t/unchecked-cast-while-overriding-return-value-by-subtype/29009/13 "2024-10-21T02:40:19Z")

</div>

Conceptually it doesn’t matter if you define mapping between label and class in enumerator or by registry. The actual problem you facing is the type erasure: JVM doesn’t know about generics and won’t be able to cast classes correctly. This is also the reason you need to provide the Class parameter to the signature of the method.  
I would suggest to request from the application the map of label to Class type (as enum, registry, or simply a Map\<String, Class\>) and generic method, which takes that Class as a first parameter and returns the instance of T.  
Inside this method they can use switch to call individual converting methods base on the Class parameter value.

Another variation would be to make this method inline. In that case it will have access to the type from the calling site without getting it explicitly as a parameter.

The enum value may define the abstract method, returning Any, or each element will implement its own method, returning its own type. In both cases the application code should “know” the type in the file. This is what you try to avoid.
