Kotlin: Type conversion with adapters | Java code geeks

I show You how To Make Huge Profits In A Short Time With Cryptos!

In this article, we will learn how to use the Kotlin extension functions to provide a simple and elegant type conversion mechanism.

Maybe you have used Sling Apache before. In this case, you probably know Use of adapter slings. We will be implementing a very similar approach in Kotlin.

Creating an extension function

With Kotlins extension functions, we can add methods to existing classes. The following declaration adds an adaptTo (..) method to all subtypes of Any.

1

2

3

fun <F : Any, T : Any> F.adaptTo(targetType: KClass<T>): T {

    ..

}

The passed targetType parameter specifies the type of target that should be returned by the method. We are keeping the method body empty for now.

Converting an object of type A to another object of type B will look like this with our new method:

1

2

val a: A = A()

val b: B = a.adaptTo(B::class)

Provide conversion rules with adapters

In order to implement the adaptTo (..) method, we need a way to define conversion rules.

For this, we use a simple Adapter interface:

1

2

3

4

interface Adapter {

    fun <T : Any> canAdapt(from: Any, to: KClass<T>): Boolean

    fun <T : Any> adaptTo(from: Any, to: KClass<T>): T

}

canAdapt (..) returns true when the implementing class is able to convert the object from to type to.

adaptTo (..) does the actual conversion and returns an object of type to.

Finding a suitable adapter

Our adaptTo (..) extension function needs a way to access the available adapters. So we create a simple list that stores our adapter implementations:

1

val adapters = mutableListOf<Adapter>()

In the extension function, we can now search the list of adapters for a suitable adapter:

1

2

3

4

5

6

7

8

fun <F : Any, T : Any> F.adaptTo(targetType: KClass<T>): T {

    val adapter = adapters.find { it.canAdapt(this, targetType) }

            ?: throw NoSuitableAdapterFoundException(this, targetType)

    return adapter.adaptTo(this, targetType)

}

class NoSuitableAdapterFoundException(from: Any, to: KClass<*>)

    : Exception("No suitable adapter found to convert $from to type $to")

If an adapter is found that can be used for the requested conversion, we call adaptTo (..) from the adapter and return the result. If no suitable adapter is found, a NoSuitableAdapterFoundException exception is thrown.

Example of use

Suppose we want to convert JSON strings to Kotlin objects using the Jackson JSON Library. A simple adapter might look like this:

01

02

03

04

05

06

07

08

09

ten

class JsonToObjectAdapter : Adapter {

    private val objectMapper = ObjectMapper().registerModule(KotlinModule())

    override fun <T : Any> canAdapt(from: Any, to: KClass<T>) = from is String

    override fun <T : Any> adaptTo(from: Any, to: KClass<T>): T {

        require(canAdapt(from, to))

        return objectMapper.readValue(from as String, to.java)

    }

}

We can now use our new extension method to convert a JSON string to a Person object:

01

02

03

04

05

06

07

08

09

ten

11

12

13

14

15

16

17

18

data class Person(val name: String, val age: Int)

fun main() {

    

    adapters.add(JsonToObjectAdapter())

    ...

    

    

    val json = """

        {

            "name""John",

            "age" 42

        }

    """.trimIndent()

    val person = json.adaptTo(Person::class)

}

You can find the source code of the examples on GitHub.

In adapters.kt you will find all the necessary parts in case you want to try it out for yourself. In example-usage.kt you will find adapter implementations and usage examples.



Source link

Leave a Reply

Your email address will not be published.