Kotlin and Java interoperability issues to be aware of

Kotlin personal use development is also a year, always wanted to summarize Kotlin and interoperable Java issue should be noted, happened to see a good summary of the article directly carry over.

Foreword

Google is currently kotlin devaluation of the Android development language, but due to historical reasons, most of our projects still or Java-based, which means that the presence of Java and Kotlin two languages ​​simultaneously developed.

Some would say the old projects are all translated into Kotlin, indeed how to do, but the cost is still getting bigger. We can only little by little, slowly migrate to kotlin language.

So in the process of migration can not be avoided in the case of Java and Kotlin call each other. That Kotlin call Java or Java call Kotlin. Here we take a look at some of the specific solutions to interoperate between the two.

kotlin call java

Nullability (nullability)

Java has a default value can be empty and kotlin no sex, so when calling Java methods do not know will not receive a null value.
So we call in Kotlin in Java when you need to add? or! Tell Kotlin there may be a null value.

For example, there is a Java method returns an array of strings do after receiving a set of strings:

public Set<String> toSet(Collection<String> elements){
    //TODO
}

So Kotlin in the time of the call can not be determined whether the input and output may be empty. We need to use? or! To assist the judge.

In order to facilitate Kotlin call, we usually use @NotNull annotation to identify non-original parameters Java code field, the return value.

@NotNull
Set<@NotNull String> toSet(@NotNull Collection<@NotNull String> elements){
    //TODO
}

The time of the call in Kotlin clearly know can not be empty, we use here is jetBrain of @NotNull notes, of course, there are other options, as shown below:

Here it is recommended to use JetBrain or Android annotations.

Prefix attribute: (getter, setter)

If you are using Java bean, then we call in Kotlin would be no problem.

If you empty parameter method begins with get, then you know that it is Kotlin getter, you can access it by property name.
If the same method is preceded by a single parameter set, then Kotlin to know that this is the setter, direct assignment by attribute name.
Of course, the principle is also and they like.

We define a Java bean:

class User {
    
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Kotlin access

val user = User()
user.name = "四爷" //赋值
val age = user.age //获取age字段值

Keywords (keywords)

There are many systems kotlin keywords defined as fun is in objects, typeof, val, var, when, typealias like.

These keywords can be used in java, but in kotlin is not enough.

Or function parameters using these keywords, then kotlin be some problems at the time of the call, such as Java defines a method called method is in. So call in Kotlin directly will give an error.

Then the easiest way is to rename the Java method, but if you call a method tripartite library, it is difficult to rename.
So we Another solution is to call java method when Kotlin plus `` backquote to use.

 Utils.`is`()

But if we can rename or renamed, the code in order to prevent too many symbols.

Any avoid using any extension method and the extended attribute

Overload operator (operator Overloading)

Operator overloading does not exist in Java, but there kotlin. such as:

a+b => a.plus(b)

In kotlin + operator in the method for translation plus.

If you use Java in the same method names, such as plus (plus), subtraction (minus) or other operators name, be sure to make sure they are compatible with the operator, to avoid accidental calls them.

Java call Kotlin

JvmName & JvmMultifileClass

When we migrate Java tool will be translated into Kotlin class or function to expand the top-level function. But after this treatment, the Java file can not be called directly, then we need to add annotations @file: JvmName ( "filename"):

Ext.kt file

@file:JvmName("ExtUtils")
package com.demo.javaAndKotlin

fun a(): String {
    ...
}

fun b(): String {
    ...
}

Here we will name the name ExtUtils. In addition, we may have other top-level functions or extended functions. According to the above in this way we can also specify one other name, but if we also want to use this name when ExtUtils will complain:

Duplicate JVM class name 

Then we need to add a new comment @file in different files: JvmMultifileClass. The merger means that all the files to a new name for the ExtUtils file.

ExtOther.kt file

@file:JvmMultifileClass
@file:JvmName("ExtUtils")
package com.demo.javaAndKotlin

fun c(str: Any): String {
   ...
}

We've also added @file in Ext.kt file: JvmMultifileClass notes, we can use ExtUtils directly in the Java file to call a (), b (), c () method has.

JvmField

We use the data type, that data class is not required to specify getter and setter in kotlin, you can access them directly by the field name. However, if the calling data class in Java files still need to use getter and setter methods call. Here we can modify them, and that is the use of @JvmField annotations by annotation can be directly exposed to the field visit.

data class Person(

    @JvmField var name: String,
    @JvmField var age: Int
)

//java中调用
Person person = new Person("",1);
person.name = "";
person.age = 10;

But there are exceptions that lateinit modified fields are automatically exposed, without specifying @JvmField comment. There is the same const modified field will be automatically exposed.

In addition, if we want to call setName in Java when modifying the attribute name is not called setName, here we need to use @set: JvmName comment. Similarly modify getName use @get: JvmName. It should be noted that the designated @set: JvmName or @get: JvmName do not need to comment after the specified @JvmField.

data class Person(

    @set:JvmName("changeName")
    var name: String,
    @JvmField var age: Int,
    @get:JvmName("likesPink")
    var likesPink: Boolean
){
    lateinit var address:String
}

JvmStatic

When we migrate files to Java static methods when Kotlin, we'll put it in the companion object, but after such treatment can not be called directly from Java file, the companion was invoked through an object instance.

class MyService {
    internal fun doWork() {
        ...
    }

    companion object {
        fun schedule(context: Context) {
            ...
        }
    }
}

//在Java中调用
MyService.Companion.schedule(this);

Fortunately Kotlin provides @JvmStatic comment. Kotlin he will generate a static method after completion of the compiler class package.

class MyService {
    internal fun doWork() {
        ...
    }

    companion object {
        @JvmStatic
        fun schedule(context: Context) {
            ...
        }
    }
}

//在Java中调用
MyService.schedule(this);

JvmOverloads

In Kotlin, we can set the default value to the parameter of the function, which is the default parameter. But this feature is not available in Java. Without doing anything, then call a function in Java when it is necessary for each parameter to be passed. So we set the default parameters would have no meaning.

So, Kotlin provides us @JvmOverloads notes, the use of this annotation, the compiler will Kotlin in left to right order of each optional parameter to generate a heavy load.

@JvmOverloads
fun Bitmap.resize(width: Int, height: Int = 200) {

}

//java调用
ExtUtils.resize(bitmap,100);

Here we can easily understand the meaning of Bitmap.resize method of Kotlin in, but when ExtUtils.resize this call, the method name is not clear enough. So we can use annotations to specify the name @JvmName.

@JvmName("resizeBitmap")
@JvmOverloads
fun Bitmap.resize(width: Int, height: Int = 200) {

}
//java调用
ExtUtils.resizeBitmap(bitmap,100);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Published 57 original articles · won praise 26 · views 40000 +

Guess you like

Origin blog.csdn.net/Ever69/article/details/104693298