Java Interoperability – Calling Kotlin from Java

When Kotlin was developed, it worked solely on JVM, hence it provides a complete set of features that makes calling Kotlin from Java, quite easy. For example, objects of Kotlin classes can be easily created and their methods can be invoked in Java methods. However, there are some rules about how Kotlin code can be used in Java.

Kotlin Properties –

A property in Kotlin is defined in Java as a private field with the same name as that of the property, and a getter and setter function, with get and set prefixed to the property name. This private field exists in the java class generated from the kotlin file.
For example, the property var age: Int, gets compiled to the following code in Java –

filter_none

edit
close

play_arrow

link
brightness_4
code

private int age;
  
public int getAge(){
  return age;
}
public void setAge(int age){
  this.age = value;
}

chevron_right


These properties can be accessed using the object of the class, in the same way as done in Java. However, if the property name begins with is, then the get keyword is skipped in the name of the getter function.



Package-level Functions –

All the functions defined in a Kotlin file, within a package are compiled into static methods in Java within a class whose classname is a combination of package name and the filename.

For example, if there is package named as kotlinPrograms and a Kotlin file named as firstProgram.kt with the following contents.

filter_none

edit
close

play_arrow

link
brightness_4
code

// Kotlin file
  
package kotlinPrograms
  
class myClass {
  
  fun add(val a:Int, val b:Int): Int {
   return a+b;
 }
}

chevron_right


This function can be invoked in Java using the following syntax:

// Java
new kotlinPrograms.firstProgram.myClass()
kotlinPrograms.FirstProgramkt.add(3, 5);

We can change the name of the generated Java class using @JvmName annotation.

filter_none

edit
close

play_arrow

link
brightness_4
code

// Kotlin file
@file : Jvmname("Sample")
  
package kotlinPrograms
  
class myClass {
  
  fun add(val a:Int, val b:Int): Int {
   return a+b;
 }
}

chevron_right


This function can be invoked in Java using the following syntax:

// Java
new kotlinPrograms.firstProgram.myClass()
kotlinPrograms.Sample.add(3, 5);

However, having multiple files with the same name is logically an error. To overcome this problem, Kotlin provides its compiler the ability to create a facade class that has a particular name and contains all the declarations from all the files with have the same name. To enable the creation of such a facade class, the annotation @JvmMultiFileClass annotation in all of the files.

Example

filter_none

edit
close

play_arrow

link
brightness_4
code

// Kotlin code
@file:JvmName("Sample")
@file:JvmMultiFileClass
  
package sample.example
  
fun print(){.......}

chevron_right


Another Kotlin file –

filter_none

edit
close

play_arrow

link
brightness_4
code

// Kotlin code
@file:JvmName("Sample")
@file:JvmMultiFileClass
  
package sample.example
  
fun printString(){.......}

chevron_right


Both these functions can be invoked in Java using the following syntax:

// Java calling statements
sample.example.Sample.print()
sample.example.Sample.printString()

Static fields –

Properties in Kotlin that are declared within a named object or a companion object, are used as static fields in Java. To access these fields in Java, these must be annotated with @JvmField annotation , lateinit modifier or must be declared with a const modifier.


Example:

filter_none

edit
close

play_arrow

link
brightness_4
code

// filename Program.kt
  
// Property in a companion object
class abc{
 companion object{
      @JvmField
      val x = 5;
  }
}
  
// A constant property
const val y = 5;

chevron_right


//Java Usage
abc.x
Programkt.y

Static methods –

The methods defined at the package level are always generated as static methods in the Java file. Also the methods defined in named objects and companion objects if annotated with @JvmStatic annotation are generated as static methods. This annotation declares the following function to be a class function.

Example for the companion object

filter_none

edit
close

play_arrow

link
brightness_4
code

// filename Programs.kt
class abc {
  companion object {
     @JvmStatic fun add(val a:Int, val b:Int):Int{
        return a+b;
      }
     fun sub(val a:Int, val b:Int):Int{
        return a-b;
      }
   }
}

chevron_right


//Java usage
abc.add(); // works fine
abc.sub(); // error: not a static method
abc.Companion.add(); // instance method remains
C.Companion.sub(); // the only way it works

Similarly, it works for named object.

Instance Fields –

Kotlin provides a feature to use a property as an instance field in Java. To do this annotate the property with @JvmField annotation. These instance fields have the same visibility as the Kotlin property. However, the property must have a backing field and must not be declared with private, open, const and override modifiers.

Example

filter_none

edit
close

play_arrow

link
brightness_4
code

// Kotlin code
class ABC(c: Int){
 @JvmField val id = c
}

chevron_right


This property now can be accessed in Java as

ABC obj = new ABC(5);
System.out.println(obj.id);

Checked Exceptions

All the exceptions in Kotlin are unchecked. Thus, Java signatures of the Kotlin functions neither declare nor handle the exceptions thrown. To overcome this problem, the Kotlin function must be annotated with the @Throws annotation specifying the exception that will be thrown. In this case, the Java signature will also declare the function to be thrown.

Example

filter_none

edit
close

play_arrow

link
brightness_4
code

// A sample Kotlin function
  
// filename program.kt
package Sample
  
fun print(){
 throws IOException()
}

chevron_right


// Java code trying to call the above  function
try {
    Sample.Program.print(); 
    }
   // This statement causes error because does not declare IOexception in throws list
   catch(IOException e) { 
}

So, to resolve error we declare @Throws annotation in the top.

filter_none

edit
close

play_arrow

link
brightness_4
code

// Overcoming the problem with @Throws annotation
package Sample
  
@Throws(IOException::class)
fun print()
{
throws IOException()
}

chevron_right




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.