Kotlin Interoperability →
We can call the java function from kotlin and the kotlin function from java and can have JAVA and KOTLIN files within the same application.
How this is possible for that we need to understand the following thing?
Let’s see first How Java Code Runs?
- Compile Time[Handled by JDK that contains Compiler] → Java code converted into Byte Code
MyDemo.java(java code) — — Compiler — → MyDemo.class(ByteCode)
2. Runtime[handled by JVM] → JVM runs that byte code
MyDemo.class(ByteCode) — —JVM— — → code up and Program Running
Now let’s see How Kotlin Code Runs?
- At Compile Time → Kotlin code converted into Byte Code
MyDemo.kt(kotlin code) — — Kotlin Compiler— — -> MyDemoKt.class(Byte Code)
2. At Runtime → JVM Runs that byte code
MyDemoKt.class(Byte Code) — -JVM — -> code up and Program Running
What happens actually when we run any kotlin file?
Assume the file name is MyFirst.kt
fun add(a: Int): Boolean {
// Method Body
}
After compilation what happens to the MyFirst.kt file?
It is converted into MyFirstKt.class
class MyFirstKt {
public static Boolean add(int a) {
// Method Body
}
}
that means kotlin code is just a wrapper for java code
Calling Kotlin function from Java file and vice-versa :
kotlin file name → MyFirst.kt
fun main(args : Array<String>)
{
}
fun add(a: Int, b: Int): Int
{
return a + b
}
converted into a java wrapper class
/**
* public class MyFirstKt
*
* public static void main(String[] args){
*
* }
*
* public static int add(int a, int b) {
* return a + b;
* }
*}
*
**/
As we have now two methods main and add in the form of java code so we can call it from any other java class
Java file name → MyJavaFile.java
public class MyJavaFile {
public static void main(String[] args) {
int sum = MyFirstKt.add(3, 4);
System.out.println("Printing sum from Java file : " + sum);
}
// we can call this method from the kotlin file
public static int getArea(int l, int b) {
return l * b;
}
}
call above getArea() from kotlin like below
fun main(args: Array<String>) {
var area = MyJavaFile.getArea(10, 5)
println("Printing area from kotlin file : " + area)
}
Output : Printing area from kotlin file : 50
Note — We can change our kotlin file name to our own customized file name using @file:JvmName(“customized file name”) and then using that name we can access methods (means it gives name to wrapper class which generated after compilation and then using that name we can access methods e.g @file:JvmName(“MyCustomKotlinFileName”) it will change kotlin file name to MyCustomKotlinFileName.
Default Function with Interoperability with @JvmOverloads:
What is Default Function?
We can pass an argument with a default value to a function such function is called a Default function. if we pass any other value than default then that value will be overridden with a new passing value.
fun findVolume(length: Int, breadth: Int, height: Int = 10): Int {
return length * breadth * height
}
var result = findVolume(2, 3)
print(result) // 2*3*10 = 60
var result = findVolume(2, 3, 20) // Overrides the default value means 10 will become 20
print(result) // 2*3*20 = 120
Note → Java doesn’t support Default Function, so we can use @JvmOverloads for Interoperability( means if we defined default function with @JvmOverloads in kotlin then we can happily access that function in the java class because it will become compatible with such change)
For example
Kotlin Code:
@file:JvmName("MyCustomKotlinFileName")
package com.myKotlin
fun main(args: Array<String>) {
var result = findVolume(2, 3, 30)
print(result)
}
// this annotation will just make this function compatible with java code
@JvmOverloads
fun findVolume(length: Int, breadth: Int, height: Int = 10): Int {
return length * breadth * height
}
Java Code
import com.myKotlin.MyCustomKotlinFileName
public class MyJavaFile {
public static void main(String[] args) {
int result1 = MyCustomKotlinFileName.findVolume(4, 7);
System.out.println(result1)
int result2 = MyCustomKotlinFileName.findVolume(4, 7, 40);
System.out.println(result2)
}
}
Output:
280 // It will use a default value that is 10 then this result will come
1120 // It will use an overridden value that is 40 then this result comes
In conclusion, Kotlin Interoperability stands as a powerful bridge in the realm of programming, enabling seamless collaboration between different languages. As we’ve explored the various strategies and best practices, it becomes evident that mastering this aspect is crucial for developers aiming to create versatile and efficient applications. The ability of Kotlin to communicate effortlessly with other languages opens up a world of possibilities, allowing for the integration of diverse technologies and enhancing the overall development experience. Embrace the potential of Kotlin Interoperability to elevate your coding skills and empower your projects with the flexibility and compatibility needed for success in the ever-evolving landscape of software development.
Happy Coding 🙂