With Google's adoption as the official language for Android, the Kotlin commune is expanding. Meanwhile, I moved from Java, which is adopted as Server Side Language, to Server Side Kotlin.
Here are some of the benefits of migrating to Kotlin. It is a light introduction because it is a language specification of the part that is often talked about.
--The Server Side Kotlin ecosystem is weak at this stage
Kotlin does not allow nulls to be assigned to variables of type non-Optional. It's very safe because the compiler guarantees it's not null. Also, if it is Optional, a check is required when retrieving the value.
fun main(vararg args: String) {
val user: User? = null
println(user?.fullName ?: "unknown")
}
data class User(val familyName: String, val firstName: String) {
val fullName: String
get() = "${this.familyName} ${this.firstName}"
}
Kotlin has a when expression similar to Scala's match. It corresponds to a switch in Java, but the difference is that it returns a value and guarantees the completeness of the enumeration.
fun method(license: License) {
val service = license.createService()
}
enum class License {
FREE,
ENETERPRISE;
fun createService(): Service {
return when (this) {
FREE -> FreeService()
ENETERPRISE -> EnterpriseService()
}
}
}
interface Service { ... }
class FreeService: Service { ... }
class EnterpriseService: Service { ... }
This (License) is passed in the when expression. We know that the License is FREE or ENTERPRISE, so we don't have to write default (or else in kotlin) processing in the when expression. Also, ** If there is an omission in the enumeration pattern, a compile error will occur, so completeness can be guaranteed *. ( There are some restrictions)
・ ・ ・
The system takes a long time to scale and take over. Kotlin comes with a valid language specification to carry them out safely. I think it's a noteworthy feature to adopt Kotlin, as the features mentioned in the benefits provide stronger support than Java.
As an aside, since the existing system was built with Spring-boot + Mavan, being able to use it as it is was also a major factor in the transition because the learning cost was significantly reduced.
Even with the benefits, there were some stumbling blocks in actual development. I would like to introduce some of them.
In Java, it is SpringApplication described as follows, but it did not work if it was generated by Spring Initializr and used.
@EnableAutoConfiguration
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Kotlin's static is implemented via Companion (as well as Scala), so write: Also, add the JvmStatic annotation so that it can be called from Java.
@SpringBootApplication
@EnableAutoConfiguration
class MyApplication {
companion object {
@JvmStatic fun main(vararg args: String) {
SpringApplication.run(MyApplication::class.java, *args)
}
}
}
Mockito's any / anyObject is implemented internally to return null. When I try to use this in Kotlin, I get an IllegalStateException exception ** when passed to a non-null argument **.
As a solution, it seems that it is possible to bypass the null check by using Kotlin's Generics. You can use the following Helper class.
class MockitoHelper {
companion object {
fun <T> any(): T {
return Mockito.any() ?: null as T
}
}
fun <T> eq(value: T): T {
return if (value != null) Mockito.eq(value)
else null ?: null as T
}
}
I referred to the article here. Thank you: bow: *** Please take into account that this solution may no longer be available **.
Even if I just dropped the Java code as usual into Kotlin, Json couldn't map it to the DataClassResource and threw an exception.
data class DataClassResource(val key: String, val value: String)
@RestController
@Component
class DataClassController {
@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = "/update", method = arrayOf(PUT), produces = arrayOf(APPLICATION_JSON_VALUE))
fun update(@RequestBody resource: DataClassResource) {
...
}
}
I call the constructor of a class with the RequestBody annotation to initialize it, but I can't seem to find the primary Kotlin constructor.
This issue can be resolved by adding a Kotlin-enabled version of the Jackson module as a dependency. Let's add the following package as a dependency.
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version>2.8.0</version>
</dependency>
Tips :cookie:
When extending static methods in Kotlin, implement them through Companion. However, Java classes do not have Companion Objects, so they cannot implement extension functions or properties such as:
fun JavaClass.Companion.extensionMethod() {
...
}
There is also an Issue on YouTrack. I want you to implement it. https://youtrack.jetbrains.com/issue/KT-11968
Java methods can be null even if they are not Optional. If you want to ensure security in the Kotlin area, it seems better to receive the result of Java method as Optional.
val maybe: String? = javaClass.method()
When defining the property to be injected with the Autowired annotation, if you define it normally, a compile error will occur due to uninitialization, so define it with lateinit
for delayed initialization.
@Component("sample")
class Sample {
@Autowired
private lateinit var dependency: Dependency
}
However, lateinit
can only be defined with var
. If you want to define with val
, use Primary Constructor.
@Component("sample")
class Sample @Autowired constructor(private val dependency: Dependency) {
}
I want to define properties that do not change with Immutable as much as possible.
We were able to proceed with development with stable velocity, despite some stumbling blocks. It's more secure at the compiler level, and your code has better visibility. I think that the power of that support will be demonstrated when scaling in the future. There is also a description peculiar to Kotlin, so it would be good to proceed while exploring in the review what kind of policy to go! However, I felt that the threshold for migrating from Java to Kotlin and the cost of learning were low again. I want Server Side Kotlin to get more and more exciting: tada:
Recommended Posts